AsyncTask 源码分析
AsyncTask 是很熟悉的一个工具类了,可以使用它来执行耗时操作(比如下载文件)。用法如下:
|
|
下面从源码的角度来分析一下整个流程:
1. AsyncTask 的构造方法分析。
|
|
从代码中可以看到,构造方法创建了两个对象。第一个匿名类对象里的回调方法 call() 里调用了 doInBackground 方法。第二个匿名类对象的回调方法 done() 方法里调用了 postResultIfNotInvoked(get()) 方法。
2. task.execute() 分析
接下来看一下 AsyncTask 的 execute() 源码:
|
|
只有一行代码。继续跟踪下去:
|
|
onPreExecute() 方法得到了执行(在主线程中)。接着执行 exec.execute(mFuture) ,实际上是执行 SerialExecutor 的 execute() 方法。
|
|
SerialExecutor 的 execute() 方法传参是 mFuture 对象,所以会执行 mFuture 对象的 run() 方法。FutureTask 的 run() 方法源码如下:
|
|
中间有一句代码 : result = c.call(); 该行代码是在子线程中执行的,c.call() 方法即为刚才第一个匿名类对象里的回调方法 call() 方法,这句意味着 doInBackground() 方法子线程中被调用了。
随后会执行 ran = true;
if (ran)
set(result);
跟踪下去会执行 finishCompletion 方法:
|
|
注意倒数第二行的 done(); 方法,它就是刚才第二个匿名类对象mFuture 的回调方法 done() 方法 也就是说postResultIfNotInvoked(get()) 方法就得到了执行。 postResultIfNotInvoked 方法调用了 postResult 方法:
|
|
这就涉及了 handler 异步消息处理。主线程中的 handler 方法会处理此消息:
|
|
MESSAGE_POST_RESULT 的消息到来时会执行 result.mTask.finish(result.mData[0]); finish 方法源码如下:
|
|
onPostExecute(result); 代表 AsyncTask 的方法 onPostExecute 得到了执行(主线程中执行)