转自:http://blog.163.com/gobby_1110/blog/static/29281715201352004329356/
深入解析AsyncTask(doInBackground不工作)
2013-06-20 12:43:29| 分类: Android问题及解|字号 订阅
AsyncTask引发的一个问题
上周遇到了一个极其诡异的问题,一个小功能从网络上下载一个图片,然后放到ImageView中,是用AsyncTask来实现的,本身逻辑也很简单,仅是在doInBackground中用HTTP请求把图片的输入流取出,然后用BitmapFactory去解析,然后再把得到的Bitmap放到ImageView中。这个应用是用4.0的SDK开发的,也是运行在4.0上面的。但是有时候下载这张图片去要用很久很久,甚至要等上几分钟。通过调试发现一个令人难以接受的事实:竟然是doInBackground()未及时执行,也就是它并没有在#execute()调用之后马上执行,而是等待了很久才得以执行。
神马情况,难道AsyncTask不是线程,难道不是异步,难道AsyncTask另有内幕?
AsyncTask的内幕
AsyncTask主要有二个部分:一个是与主线各的交互,另一个就是线程的管理调度。虽然可能多个AsyncTask的子类的实例,但是AsyncTask的内部Handler和ThreadPoolExecutor都是进程范围内共享的,其都是static的,也即属于类的,类的属性的作用范围是CLASSPATH,因为一个进程一个VM,所以是AsyncTask控制着进程范围内所有的子类实例。
与主线程交互
与主线程交互是通过Handler来进行的,因为本文主要探讨AsyncTask在任务调度方面的,所以对于这部分不做细致介绍,感兴趣的朋友可以去看AsyncTask的源码
线程任务的调度
内部会创建一个进程作用域的线程池来管理要运行的任务,也就就是说当你调用了AsyncTask#execute()后,AsyncTask会把任务交给线程池,由线程池来管理创建Thread和运行Therad。对于内部的线程池不同版本的Android的实现方式是不一样的: