AsyncTask 使用须知

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的源代码可以从下面网址获得:

https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/os/AsyncTask.java

  • 2. 在程序运行时检测当前的版本,来调用不同的函数

由于targetSdkVersion 的不同,导致后一种情况还有点复杂, 如果您在AndroidManifest.xml文件中设置了targetSdkVersion :

如果没有设置targetSdkVersion ,则等同于minSdkVersion的值。来看看在Android 3.1.X (Api level 12,HONEYCOMB_MR1)中 AsyncTask.javaActivityThread.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代码到应用中去。

 
原文地址:https://www.cnblogs.com/maxinliang/p/3135794.html