AsyncTask类的初始化过程
初始化阶段:
- 初始化线程池
THREAD_POOL_EXECUTOR
。用于执行任务。 - 构造一个负责调度线程的线程池的Executor
SerialExecutor
,用于任务的排队,维护AsyncTask的任务串行执行。 - 构造一个sHandler
InternalHandler
。负责将执行结果从线程切换到主线程(UI线程)。
AsyncTask内部的线程是通过一个线程池负责调度执行 :
构造THREAD_POOL_EXECUTOR
|
|
AsyncTask的线程池不同于Java中通过
Executors.newFixedThreadPool(int nThreads)
创建的线程池。
Java的newFixedThreadPool
|
|
比较两者可知 :
- FixedThreadPool的核心线程池容量和最大线程池容量相等。
- FixedThreadPool的缓存队列为没有数量限制的LinkedBlockingQueue。
- FixedThreadPool的空闲线程的等待时间为0,线程完成之后就会被回收。
- AsyncTask的核心线程池容量和最大线程池容量都与当前设备的CPU核心数有关。
- AsyncTask的缓存队列有最大容量限制。
- AsyncTask的空闲线程会等待60s才被回收。
这样的差别就使得AsyncTask不适合做耗时线程的操作。如果一个线程太耗时,线程池又满了,那后面的线程就会一直等待。
线程池的配置参数
|
|
线程池缓存队列为LinkedBlockingQueue
|
|
新建线程的工厂方法
|
|
SerialExecutor
创建AsyncTask实例
AsyncTask实例主要拥有以下属性 :
- WorkerRunnable<Params, Result> mWorker : 实现了Callable接口
- FutureTask
mFuture : 一个并发类,充当Runnable的作用。 - volatile Status mStatus : 当前AsyncTask的状态 : PENDING,RUNNING,FINISHED
- AtomicBoolean mCancelled : 任务是否被取消
- AtomicBoolean mTaskInvoked : 任务是否执行
执行任务
Executor的execute方法 :
AsyncTask内部的SerialExecutor实现了Executor接口,提供了execute方法的实现
private static class SerialExecutor implements Executor {
final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
Runnable mActive;
public synchronized void execute(final Runnable r) {
mTasks.offer(new Runnable() {
public void run() {
try {
r.run();
} finally {
scheduleNext();
}
}
});
if (mActive == null) {
scheduleNext();
}
}
protected synchronized void scheduleNext() {
if ((mActive = mTasks.poll()) != null) {
THREAD_POOL_EXECUTOR.execute(mActive);
}
}
}
首先把FutureTask对象插入到队列mTasks中,如果这个时候没有正在活动的AsyncTask任务,就会调用 scheduleNext() 来执行下一个任务。
同时,当mTask队列中的FutureTask对象执行完成之后,也会调用 scheduleNext() 来执行下一个任务。
这就证明AsyncTask是串行执行的,同一时刻只能有一个处于活动状态的任务。下一个必须等上一个执行完成之后,才能执行。
FutureTask对象执行任务是通过调用自己的run
方法,在run
方法中会调用 mWoker 的 call 方法。
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
return postResult(doInBackground(mParams));
}
};
mWorker首先把mTaskInvoked设为 true 表示,当前任务已经被调用过了。然后执行 AsynckTask 的 doInBackground 方法,接着将返回值传递给 postResult 方法。
postResult的实现
|
|
postResult 方法通过 sHandler 发送一个 MESSAGE_POST_RESULT 消息。
sHandler的实现
|
|
sHandler 是一个静态对象的,在类加载时就被创建。为了能将消息从线程池传递到主线程,就要求AsyncTask类必须在主线程中加载,否则同一个进程中的AsyncTask无法正常工作。Android系统会在Application启动时调用AsyncTask的init方法。
sHandler 收到 MESSAGE_POST_RESULT 消息后会调用 AsyncTask 的 finish 方法。
finish方法
|
|
如果 AsyncTask 任务被取消了,就调用 onCancelled 方法,否则调用 onPostExecute 方法。
在Android 3.0 开始,AsyncTask 多加了一个线程池SerialExecutor来串行执行任务。
想让AsyncTask并行执行,可以调用executeOnExecutor(Executor exec, Params... params)
传入自己的线程池。也可以直接使用AsyncTask的线程池。
例如
|
|