最近发现了一个奇怪的问题,一处很久前写的代码,通过AsyncTask的doInBackground进行后台处理,突然间不管用了,就是说doInBackground没有被执行。同事查询SVN,发现相关代码没有过任何更改,经过很久的检查,发现只有在Manifest中有一处很小的改动,就是添加了targetSDKVersion。将这个属性去掉,就没有问题了。
通过对源码和google group以及stackoverflow的各种查找和测试,发现google挖了两个坑,不幸的是,我们跳了。
第一个坑:AsyncTask在Android各个版本中可以算是频繁修改了,比较各版本代码发现,修改过多次,而且这种修改会导致很大的差别。最坑的修改是在Android 4.0开始的,AsyncTask的中execute方法的实现在4.0以前是采用Thread pool executor,各个版本对线程池中的可并行线程数限制不同,但毕竟多个Task是多线程并行。而在4.0开始,改为用serial executor,就是说同一时间只能有一个线程运行,其他线程必须等待该线程完成之后才能开始执行,因此就变成了串行的worker thread。
第二个坑:targetSDKVersion,这个属性其实很多开发者都没有注意到,Google在官方文档中的解释又十分复杂,导致它出了问题就很难定位。总的来说,这个属性是Google为了进行兼容性检查来设置的,有一些API,例如AsyncTask这种,会根据它的设置来选择执行方式。如果targetSDKVersion设置成了4.0,那么系统就认为你的应用在4.0版本上有了足够的测试,不会有问题,那么会选择4.0的各种新特性,就是说用serial executor来实现AsyncTask。如果不加入targetSDKVersion,默认这个值会等于minSDKVersion,这时候系统认为你没有在4.0版本上测试,为了防止出问题,在4.0手机上会采用Thread pool executor来实现AsyncTask。因此就导致了我们之前的问题。
Google对AsyncTask增加了一个方法,executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, ....);通过这个方法可以强制系统用Thread pool executor实现。但是需要API level 11,调用也会很麻烦。还是要注意逻辑,对长时间占用背景线程的操作避免用AsyncTask,或者自己写一个AsyncTask更靠谱一些。
相关推荐
AsyncTask源码(版本:Android4.3,含注释)
利用android.os.AsyncTask类完成MP3下载,采用进度条动态显示下载的百分比。是学习AsyncTask不错的例子。
自己写了一个基于httpurlconnection和Asynctask的例子
Handler与AsyncTask使用示例,Handler AsyncTask 示例 looper
AsyncTask的用法
AsyncTask与Handler实现进度条的方式
最新AsyncTask源码
AsyncTask_简单演示AsyncTask异步操作,写一个简单的AsyncTask异步操作解决上一篇文章提到的线程阻塞问题,对应我的博客《网易博客迁移:Android专题之AsyncTask(二)简单演示AsyncTask异步操作》,有问题欢迎留言...
Android中使用ListView数据异步加载与AsyncTask,获取网络资源,线程池技术,多线程技术。
Android AsyncTask异步处理下载网页
在新版本Android SDK中AsyncTask,应该注意在默认情况下AsyncTask是在一个单线程中调用队列中的Task。例如:有多个AsyncTask任务同时开始调用。但是执行的时候是串行的。 这个例子用作测试。
AsyncTask 断点下载
android 任务后台处理事物 asyncTask封装
Android Handler AsyncTask 异步加载
AsyncTask的执行分为四个步骤,每一步都对应一个回调方法,这些方法不应该由应用程序调用,开发者需要做的就是实现这些方法。 1) 子类化AsyncTask 2) 实现AsyncTask中定义的下面一个或几个方法 ...
Android AsyncTask实例,测试ok。
AsyncTask.java,AsyncTask.java,AsyncTask.java,AsyncTask.java
Android AsyncTask的简单Demo,对应Blog文章:http://blog.csdn.net/dolacmeng/article/details/50215519
AsyncTask_演示线程阻塞,对应我的博客《Android专题之AsyncTask(一)基本概念介绍》,有问题欢迎留言讨论。
Handler,AsyncTask,Looper自定义线程使用示例,自定义线程与UI线程交互,访问UI线程控件