【问题标题】:execute the async task in serial order in android4.0在android4.0中按顺序执行异步任务
【发布时间】:2012-08-19 19:13:51
【问题描述】:

我已经实现了 2 个异步任务,我使用的是 android4.0。其中一个异步任务连续执行,第二个根据要求执行(可能是多次)。 例如。

class AsynTask1 exetends AsyncTask<Void, Bitmap, Void>{
    protected Void doInBackground(Void... params) {
        while(true){
            publishProgress(bmp);
        }
    }
}

class AsynTask2 extends AsyncTask<String, Void,Void>{
    protected Void doInBackground(String... params){
        System.out.println(params[0])
    }
}

在活动课中

class MainActivity extends Activity{
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        new AsynTask1().execute();

        int i=0;
        while(i<100)
        {
            if(i%2==0)
            new AsynTask2().execute("no is even"+i);
            i++
        }
    }
}     

在上述情况下,AsynTask2 没有被执行。

如果尝试使用 executeOnExecutor(AsyncTask.THREAD_POOL_Executor,params),那么两个 asyntask 都被执行,我从 AsynTask2 获取打印消息,但这些消息不按顺序排列(如 0 2 6 4 10 8 12 14 ... .).

有什么办法可以连续执行 AsynTask1 并按顺序执行 AsynTask2 以防止顺序(如 0 2 4 6 8 10 12 14....)。

感谢和问候 迷你。

【问题讨论】:

    标签: android concurrency android-asynctask


    【解决方案1】:

    尝试使用回调。在 AsyncTask 类中定义接口并在主类中实现它们。使用 AsyncTask2 的 onPostExecute 上的回调来启动下一个 AsyncTask2。你会保证订单。

     class AsyncTask2 extends AsyncTask<String, Void,Boolean<{
            //Your code. doInBackground must now return a boolean.
            protected Void onPostExecute(final Boolean success){
                myCallback listener = (myCallback) parentActivity;
                listener.call();
            }
    
            public Interface myCallback{
                void call();
            }
     }
    

    然后在您的主要活动中实现 myCallback。

    [编辑]

    这是你可以做的一个示例。

    Class MainActivity extends Activity implements myCallback{
        //Your code
        public void call(){
           new AsyncTask2().execute("no is even" + i);
        }
    }
    

    【讨论】:

    • 感谢您的回复,但我不知道回调及其实现。
    【解决方案2】:
    1. 您不应该将 AsyncTask 用于长时间运行的线程(实现 AsyncTask1 的方式)。请参阅文档:http://developer.android.com/reference/android/os/AsyncTask.html。只需为 AsyncTask1 正在执行的操作创建一个单独的线程。

    2. 由于您需要串行执行您在 AsyncTask2 中执行的操作,因此可以通过创建大小为 1 的 ThreadPool 来完成。

      // Creating ThreadPool
      ExecutorService service = Executors.newFixedThreadPool(1);
      
      // Submitting task
      service.execute(task);
      
      // Shutting down the thread pool when not required.
      service.shutdown();
      

    【讨论】:

      【解决方案3】:

      SERIAL_EXECUTOR 用于 Asynctask2

       new AsynTask2().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR ,"no is even"+i)
      

      编辑: 用于 Asynctask1 ,因此不使用相同的执行器

       new AsynTask1().executeOnExecutor(AsyncTask.THREAD_POOL_Executor,params);
      

      【讨论】:

      • 我试过这个,但是 AsyncTask2 没有被执行,所以我没有从 AsynTask2 得到消息。所有异步任务的线程池是否相同?
      • 你是只为 Asynctask2 还是为 asynctask1 这样做?
      • 我在两个 AsynTasks 上都试过这个,后来我只在 AsynTask2 上试过。
      • 好的..我编辑了我的答案。原来正常执行使用串行执行器,所以将 Aynctask1 放在线程池执行器上
      • 它位于链接 i shared。搜索 SerialExecutor
      【解决方案4】:
          int i=0;
          while(i<100)
          {
            new AsynTask1().execute();
              if(i%2==0)
            {
              new AsynTask2().execute("no is even"+i);
             }
              i++
          }
      

      【讨论】:

      • 如果我使用上面的,那么每次迭代都会调用 AsynTask1,我不想每次迭代都调用 AsynTask1。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-30
      • 1970-01-01
      • 2022-08-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多