运行并行 AsyncTask

Posted

技术标签:

【中文标题】运行并行 AsyncTask【英文标题】:running parallel AsyncTask 【发布时间】:2012-12-04 07:59:59 【问题描述】:

我的应用程序中有一个 SplashActivity,它在我启动应用程序时使用 AsyncTask 执行一些操作。

我还创建了另一个从服务器下载数据的 AsyncTask。现在,在我关闭应用程序后,AsyncTask 仍在下载数据。

但是当我再次启动我的应用程序时,我的 SplashActivity 的 AsyncTask 不会执行其后台(doInBackground 函数),直到我的下载器 AsyncTask 完成,并且我的应用程序被挂起。

所以我的问题是我们不能并行运行两个 AsyncTask 吗?两个 AsyncTask 都是不同的并且做自己的事情。 有什么办法吗。

【问题讨论】:

请贴出相关代码(Tasks和调用Activity) 【参考方案1】:

Honeycomb 版本中的 AsyncTask 发生了变化。旧版本有一个 10 个线程的线程池,因此您可以并行运行 10 个任务。但是对于 Honeycomb 及更高版本,默认是串行执行器,它会一个接一个地执行任务。但是你可以传递一个ThreadPoolExecutor 来执行:

   if (Build.VERSION.SDK_INT >= 11) 
     //--post GB use serial executor by default --
     task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    else 
     //--GB uses ThreadPoolExecutor by default--
     task.execute();
   

【讨论】:

不需要指定最后一个参数new Void[];省略它就足够了。 你的IDE错了;可变参数是创建数组的快捷方式,因此参数列表当然可以为空。实际上,提供像您这样的新数组实际上是不好的做法。你不必要地实例化一个对象。 GC 将需要出现并暂停您的应用几毫秒以再次清理它。 谢谢!奇迹般有效。 android 文档对此再清楚不过了:“public static final Executor THREAD_POOL_EXECUTOR。在 API 级别 11 中添加 - 可用于并行执行任务的 Executor。”【参考方案2】:

您需要使用thread pool Executor 来执行AsyncTask。默认实现使用在单线程上运行的串行执行器

所以创建一个ThreadPoolExecutor 然后使用

AsyncTask 的 executeOnExecutor 而不仅仅是执行方法

【讨论】:

使用这种方法有什么缺点吗? IE。您是否需要通过使 AsyncTask 并行来做一些额外的工作? @Gee.E 使用默认执行器更好,因为只有一个线程实例化,所以如果您没有同时运行太多任务,默认执行器提供更好的性能,但如果有一个异步任务需要很多时间,你可能需要一个 ThreadPoolExecutor @nandeesh Roger,我正在使用并行任务从缓存数据库中获取数据。由于复杂的原因,我需要 fetcher-task 并行运行,但由于它所花费的时间可以忽略不计,我没有看到任何性能下降。无论如何,感谢您解释问题。 需要注意的是executeOnExecuter会产生Data race,所以要小心。【参考方案3】:

另一种选择是使用支持 v.4 库中的 AsyncTaskCompat。

AsyncTaskCompat.executeParallel(new AsyncTask<Void, Void, Object>() 
    @Override
    protected Object doInBackground(Void... params) 
        // do your parallel task here
        return null;
    

    @Override
    protected void onPostExecute(Object result) 
        // and fetch result
    
);

【讨论】:

此类在 API 级别 26 中已弃用并在 API 级别 27 中删除

以上是关于运行并行 AsyncTask的主要内容,如果未能解决你的问题,请参考以下文章

在 OpenMP 并行代码中,memset 并行运行有啥好处吗?

Promise.all 同时或并行运行 [重复]

并行运行异步查询 (IAsyncEnumerable)

并行运行 RSelenium

如何并行运行机器人框架测试用例而不是并行测试套件?

如何将python for循环从顺序转换为并行运行