【问题标题】:Doing different things after AsyncTask executes?AsyncTask 执行后做不同的事情?
【发布时间】:2017-07-01 21:16:49
【问题描述】:

您好,我对 android 编程还是比较陌生,最近偶然发现了一个关于 AsyncTasks 的相当抽象的问题。

据我了解,在 AsyncTask 执行 runInBackground 之后,它会向 onPostExecute 返回一个值,并在其中执行 UI 线程处理结果。现在,如果我想对从 runInBackground 返回的结果做不同的事情怎么办。我见过这样的建议示例(取自here):

private class MyCustomAsyncTask extends AsyncTask<Void, Void, Void>{

    private boolean mShouldCallMethod1;

    public MyCustomAsyncTask(boolean shouldCallMethod1){
        mShouldCallMethod1 = shouldCallMethod1;
    }

    @Override
    protected Void doInBackground(Void... params) {
        //code goes here..
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        if(mShouldCallMethod1){
            method1();
        }else{
            method2();  
        }
    }

}

但是如果我想要 onPostExecute 应该做的多于两件事(例如 method3、method4 等等?当然,我可以实现一个 switch 和一些 int 变量来确定调用什么方法等,但这似乎很愚蠢和多余。不管目的如何,函数返回结果的模型对我来说似乎很直接。但是在 AsyncTask 中,似乎我必须指定一个目的。我想知道是否有AsyncTask 可以实现类似函数的方式。

例如,我有一个使用 URL 获取图像的 AsyncTask。此图像可用于填充ImageView,也可保存到图库中。所以他们在runInBackground 中基本上做了同样的事情,但他们的结果需要以不同的方式处理。

我还是个初学者,如果我错过了一些简单的细节/概念,我深表歉意。 提前谢谢你。

【问题讨论】:

  • 如果他们做不同的事情,你应该写不同的异步任务
  • @cricket_007 感谢您的回复。是的,我考虑过这一点,但这意味着我必须一遍又一遍地写一堆相同的东西,这似乎也是多余的。不过,如果没有其他办法,那就不得不这样做了。
  • 答案实际上取决于您要实现的目标,并且提供的代码示例过于随意。 AsyncTask 将提供哪些数据作为参数onPostExecute?我假设它将属于同一类型,那么它的处理方式需要改变什么?
  • @PPartisan 感谢您的回复。我为歧义道歉。是的,onPostExecute 得到的数据是同一类型的。我没有任何具体的代码示例,但我会在原始问题中提供一个简单的示例。
  • 已经停止使用 AsyncTasks :trollface:。还有更好的选择

标签: java android android-asynctask


【解决方案1】:

如果您认为交换机是愚蠢的,那么您有良好的 OO 直觉。通常有充分的理由避免使用AsyncTask。但是把它放在一边,专注于你的问题......

如果你有一堆AsyncTasks 在doInBackground 中做同样的事情但需要在onPostExecute 中做不同的事情,这是匿名子类化的经典案例。首先,在您的MyCustomAsyncTask 中实现doInBackground。然后在您的Activity 或您需要使用它的任何地方,声明并使用匿名子类。

mAsyncTask = new MyCustomAsyncTask(/* constructor params */) {
    @Override
    protected void onPostExecute(Void result) {
        // can access activity members here
        mAsyncTask = null;
    }
}.execute();    

确保在onPauseonDestroy 中取消正在运行的任务。

if(mAsyncTask != null) {
    mAsyncTask.cancel();
    mAsyncTask = null;
}

【讨论】:

  • 感谢您的回答。在挖掘了很多类似的问题(可能还不够)之后,我从未见过这个解决方案。它看起来正是我需要的!
【解决方案2】:

从哪里调用 asyncTask 将决定您放置图像的用途。您将图像返回到该点并将其用于您拨打电话的目的。

【讨论】:

  • 感谢您的回答。愚蠢的问题:我应该如何将图像“返回”到我调用 AsyncTask 的原始点,它们不是在不同的线程上吗?
  • 今天早些时候 Fencer300 已经回答了这个问题,请参阅:stackoverflow.com/questions/44858053/…
  • 我关于比赛条件的问题和 Gabe Sechan 的有用回答也可能有帮助。见stackoverflow.com/questions/44864075/…
  • @Kevin Krumwiede 上面的匿名子类解决方案很简洁。
  • 感谢您的跟进,我已经看到了.get() 的解决方案。但是,我注意到有人说它冻结了 UI 线程(不确定)?
猜你喜欢
  • 2013-09-03
  • 2017-12-05
  • 1970-01-01
  • 2020-10-27
  • 2015-11-01
  • 2022-01-10
  • 1970-01-01
  • 1970-01-01
  • 2022-01-05
相关资源
最近更新 更多