AsyncTask 是从Android 1.5(Api Level 3)中引入的, 在1.5发布的年代,为了在1.5之前的版本中使用AsyncTask, 都是把AsyncTask 源代码复制到项目中使用的。 现在市场上低于1.5版本的Android手机几乎都销声匿迹了,所以也开始使用系统的AsyncTask了。
但是Android系统的AsyncTask 在执行顺序上,每个版本是有些变化的。
在1.5中初始引入的时候, AsyncTask 执行( AsyncTask.execute() )起来是顺序的,当同时执行多个 AsyncTask的时候,他们会按照顺序一个一个执行。前面一个执行完才会执行后面一个。这样当同时执行多个比较耗时的任务的时候 可能不是您期望的结果。
在android 1.6(Donut) 到 2.3.2(Gingerbread)中,AsyncTask的执行顺序修改为并行执行了。如果同时执行多个任务,则这些任务会并行执行。 当任务访问同一个资源的时候 会出现并发问题.
而在Android 3.0(Honeycomb)以后的版本中,AsyncTask又修改为了顺序执行,并且新添加了一个函数 executeOnExecutor(Executor),如果您需要并行执行,则只需要调用该函数,并把参数设置为并行执行即可。
如果您的应用依赖AsyncTask 执行的顺序,则您有两种做法
- 1. 复制一个最新的AsyncTask 源代码 ,放到您的项目中去,然后修改为您需要的执行顺序, AsyncTask的源代码可以从下面网址获得:
- 2. 在程序运行时检测当前的版本,来调用不同的函数
由于targetSdkVersion 的不同,导致后一种情况还有点复杂, 如果您在AndroidManifest.xml文件中设置了targetSdkVersion :
如果没有设置targetSdkVersion ,则等同于minSdkVersion的值。来看看在Android 3.1.X (Api level 12,HONEYCOMB_MR1)中 AsyncTask.java 和 ActivityThread.java 的代码:
在AsyncTask.java 中有个函数:
1
2
3
4
|
/** @hide */ public static void setDefaultExecutor(Executor exec) { sDefaultExecutor = exec; } |
而在ActivityThread.java 有段代码(3431行):
1
2
3
4
5
6
|
// If the app is Honeycomb MR1 or earlier, switch its AsyncTask // implementation to use the pool executor. Normally, we use the // serialized executor as the default. This has to happen in the // main thread so the main looper is set right. if (data.appInfo.targetSdkVersion AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } |
上面的代码表明在Android 3.1版本中,如果设置不同的targetSdkVersion则导致AsyncTask的执行顺序是不一样的,如果设置为小于13,则AsyncTask是并行执行的;如果设置为13,则会顺序执行。
所以 如果您的应用对执行顺序要求非常严格,则还是建议复制一份最新的代码放到项目中去吧。但是这样就无法享受新版本中AsyncTask增加的功能了,当然 如果不怕麻烦 您可以在每次Android新版本发布的时候,都复制一个最新的AsyncTask代码到应用中去。