运行并行 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的主要内容,如果未能解决你的问题,请参考以下文章