【问题标题】:Android AsyncTask - Order of executionAndroid AsyncTask - 执行顺序
【发布时间】:2012-11-05 08:00:03
【问题描述】:

我遇到了关于 AsyncTasks 执行顺序的问题。

我的问题是:

假设我有 2 个 AsyncTask 实现:MyAsyncTask1MyAsyncTask2

按以下方式调用:

new MyAsyncTask1 ().execute ();
new MyAsyncTask2 ().execute ();

是否保证 MyAsyncTask1MyAsyncTask2 之前执行? 可以肯定的一件事是,它们不会并行执行,因为使用了默认执行程序,即 SERIAL_EXECUTOR。 问题在于执行顺序:哪个先执行??

如果执行顺序未确定,如何强制执行 AsyncTasks 的执行顺序??

我需要在 MyAsyncTask2 之前执行 MyAsyncTask1,但情况并非总是如此,尽管我之前为 MyAsyncTask1 调用了执行MyAsyncTask2

我实际上拥有的是一个自定义活动:

public abstract class CustomActivity extends Activity {

    @Override
    protected void onCreate ( Bundle savedInstanceState ) {
        super.onCreate ( savedInstanceState );
        new MyAsyncTask2 ().execute ();
    }
}

还有另一个继承自自定义活动的活动:

public class MainActivity extends CustomActivity {

    @Override
    protected void onCreate ( Bundle savedInstanceState ) {
        new MyAsyncTask1 ().execute ();
        super.onCreate ( savedInstanceState );
    }
}

所以如果我使用 MainActivityMyAsyncTask1 应该在 MyAsyncTask2 之前执行,至少这是我需要的行为。

【问题讨论】:

  • 从 MyAsyncTask1 的 onPostExecute 启动 MyAsyncTask2,然后始终在 MyAsyncTask2 之前执行 MyAsyncTask1
  • 您好 imran khan,感谢您的建议,但由于我的设计,这是不可能的。我根本不想调用 MyAsyncTask1 的其他活动(使用继承)使用 CustomActivity(和 MyAsyncTask2)。
  • 然后只需将 Activity 名称传递给您希望从中启动 MyAsyncTask2 的 CustomActivity(和 MyAsyncTask2)构造函数,或者将 null 用于您不想启动 MyAsyncTask2 的其他活动
  • 或者您可以在 CustomActivity(和 MyAsyncTask2)中使用 context.getPackageManager().getClass(); 来获取用户当前查看的活动的名称

标签: android android-asynctask


【解决方案1】:

确保两个线程(基本上就是 AsyncTasks)按您想要的顺序执行的唯一方法是在第一个线程完成时启动第二个线程。

在您的情况下,为了保持实现抽象并且不必在 AsyncTask1 的 onPostExecute 中实际调用 AsyncTask2(Anup 和 Sanket 建议的方式,如果您想混合它们也可以),让 AsyncTask1 调用 @987654322 @,其中executeAsyncTask2() 是您的 CustomActivity 中的一个方法,它启动第二个 AsyncTask

【讨论】:

  • 你好 zrgiu !你实际上理解了我的设计。如果我要使用您的建议,那么您建议如何在 CustomActivity 中调用 MyAsyncTask2 ? (除了在每个子类中调用你建议的方法)
  • 因为您的 AsyncTask1 必须以某种方式从另一个类调用该方法,所以我看不到任何其他方式。对不起
【解决方案2】:

为了“链接”任意数量的 AsyncTask,我所做的是让我的 AsyncTask 接收一个自定义回调作为参数。你只需要像这样定义它:

public interface AsyncCallback(){
    public void onAsyncTaskFinished();
}

您的 AsyncTask 实现构造函数应该有一个 AsyncCallback 作为参数,如下所示:

private AsyncCallback callback;

public AsyncTaskImplementation(AsyncCallback callback){
    //Do whatever you're doing here
    this.callback = callback;
}

当然如果他们有更多的参数,不要删除它们。

那么,就在onPostExecute结束之前,介绍一下:

if (callback != null) callback.onAsyncTaskFinished();

所以,如果你传递一个回调,AsyncTask 将在主线程中执行你的回调。如果您不想执行任何回调,只需传递null

所以,要调用你的 AsyncTask 链,你只需要这样写:

new AsyncTask1(new AsyncCallback(){

    public void onAsyncTaskFinished(){
         new AsyncTask2(null).execute();
    }

}).execute();

我希望这对你有帮助;-)

【讨论】:

    【解决方案3】:

    在第一个 Aysnc 任务结束时调用你的第二个异步任务(即在你的第一个异步任务的 onPostExecute() 方法结束时)

    //first async task's onPostExecute method
    
    onPostExecute()
    {
    //do your stuff and call second async task
    
    new MyAsyncTask2 ().execute ();
    
    }
    

    这将保证在第一个任务之后以简单而优雅的方式执行第二个任务。

    【讨论】:

      【解决方案4】:

      在任务 1 的 onPostExecute 中调用 2nd Task 作为

      @Override
      protected void onPostExecute(String string){//String or whatever u passed
          new MyAsyncTask2 ().execute ();
      }
      

      【讨论】:

        【解决方案5】:

        AsyncTask 在后台执行,因此在您的情况下,第一个代码将启动 task1 并立即启动 task2.. 所以调用

        new MyAsyncTask2 ().execute ();
        

        这在 Task1 的后执行

        【讨论】:

          【解决方案6】:

          不要让事情变得复杂,并尽量保持您的设计简洁明了。两个 AsyncTask 之间的竞争取决于它们在覆盖的方法中进行的处理量。从逻辑上讲,如果您希望 AsyncTask1 在 AsyncTask2 之前完成,那么只需在第一个 Async 中添加第二个 Async 的代码块。

          或者从您的第一个 Async 的 onPostExecute 启动您的第二个 Async - 但就个人而言,这似乎没有必要。

          【讨论】:

          • 你好瓦卡斯。谢谢你的建议,但我相信我的设计很简单。主要思想是:我在很多情况下都在使用CustomActivity(使用继承),每种情况都有自己的实现; CustomActivity 拥有共同的基本部分,而它的每个子类都添加了特定的内容。所以我不能简单地将 AsyncTask2 的内容添加到 AsyncTask1 中。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-12-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多