源码颇析AsyncTask工作原理
Android开发中经常会用到AsyncTask开启异步任务,后台执行耗时操作,具体用法参考《AsyncTask:异步任务》。现在从源码来看看AsyncTask的实现机制。
1、AsyncTask中的线程池
AsyncTask中封装了两种Executor,一个是顺序执行的SERIAL_EXECUTOR,另一个是并发执行的THREAD_POOL_EXECUTOR。
1.1、SERIAL_EXECUTOR
sDefaultExecutor:默认的任务执行器。
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;SERIAL_EXECUTOR是SerialExecutor类型的线程池。
/**
* 可以按顺序一次执行一个任务
*/
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();SerialExecutor定义在AsyncTask中的静态内部类:
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);
}
}
}1.2、THREAD_POOL_EXECUTOR
THREAD_POOL_EXECUTOR并发执行任务的线程池,初始化如下:
/**
* Executor可用于并行执行任务
*/
public static final Executor THREAD_POOL_EXECUTOR;
static {
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(), sThreadFactory);
threadPoolExecutor.setRejectedExecutionHandler(sRunOnSerialPolicy);
THREAD_POOL_EXECUTOR = threadPoolExecutor;
}配套的一线参数:核心线程数、最大线程数等定义如下,随着Android API版本的升级可能不太一样,以前定义的是和CPU核数有关,现在是写死的固定数值。
private static final int CORE_POOL_SIZE = 1;
private static final int MAXIMUM_POOL_SIZE = 20;
private static final int BACKUP_POOL_SIZE = 5;
private static final int KEEP_ALIVE_SECONDS = 3;
private static final ThreadFactory sThreadFactory = new ThreadFactory() {
private final AtomicInteger mCount = new AtomicInteger(1);
public Thread newThread(Runnable r) {
return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
}
};2、AsyncTask创建初始化
2.1、AsyncTask构造函数
默认无参构造函数:必须在UI主线程上调用构造函数。
/**
* 创建一个新的异步任务。必须在UI线程上调用此构造函数。
*/
public AsyncTask() {
this((Looper) null);
}外一个有参构造函数,传入的是Handler。
public AsyncTask(@Nullable Handler handler) {
this(handler != null ? handler.getLooper() : null);
}前面这两个够构造函数最终调用的都是:
public AsyncTask(@Nullable Looper callbackLooper) {
mHandler = callbackLooper == null || callbackLooper == Looper.getMainLooper()
? getMainHandler()
: new Handler(callbackLooper);
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);
Result result = null;
try {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
result = doInBackground(mParams);
Binder.flushPendingCommands();
} catch (Throwable tr) {
mCancelled.set(true);
throw tr;
} finally {
postResult(result);
}
return result;
}
};
mFuture = new FutureTask<Result>(mWorker) {
@Override
protected void done() {
try {
postResultIfNotInvoked(get());
} catch (InterruptedException e) {
android.util.Log.w(LOG_TAG, e);
} catch (ExecutionException e) {
throw new RuntimeException("An error occurred while executing doInBackground()",
e.getCause());
} catch (CancellationException e) {
postResultIfNotInvoked(null);
}
}
};
}2.2、内部Handler:线程间通信
初始化内部Handler mHandler。同时还提供一个私有get方法获取当前AsyncTask的Handler,当然是为了内部方便。
private final Handler mHandler;
private Handler getHandler() {
return mHandler;
}通过方法getMainHandler()获取内部定义的InternalHandler类型的静态成员变量sHandler,赋值给当前AsyncTaskmHandler。
private static Handler getMainHandler() {
synchronized (AsyncTask.class) {
if (sHandler == null) {
sHandler = new InternalHandler(Looper.getMainLooper());
}
return sHandler;
}
}InternalHandler是定义在AsyncTask中的静态内部类,可以看到主要处理子线程中执行发出的消息:MESSAGE_POST_RESULT、MESSAGE_POST_PROGRESS。也就是执行结果和执行进度,这两个方法是运行在主线程的。
private static class InternalHandler extends Handler {
public InternalHandler(Looper looper) {
super(looper);
}
public void handleMessage(Message msg) {
AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj;
switch (msg.what) {
case MESSAGE_POST_RESULT:
// 只有一个结果
result.mTask.finish(result.mData[0]);
break;
case MESSAGE_POST_PROGRESS:
result.mTask.onProgressUpdate(result.mData);
break;
}
}
}AsyncTaskResult是内部封装的当前AsyncTask和数据(执行结果/执行进度),方便通过Message的obj一次携带传回到主线程。
private static class AsyncTaskResult<Data> {
final AsyncTask mTask;
final Data[] mData;
AsyncTaskResult(AsyncTask task, Data... data) {
mTask = task;
mData = data;
}
}2.3、构造Callable和FutureTask
两个重要的变量:Callable:mWorker和FutureTask:mFuture。
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);
Result result = null;
try {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
result = doInBackground(mParams);
Binder.flushPendingCommands();
} catch (Throwable tr) {
mCancelled.set(true);
throw tr;
} finally {
postResult(result);
}
return result;
}
};mWorker是Callable接口类型,不过多封装了一下,为了传入运行时的参数mParams。
private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
Params[] mParams;
}注意一个细节,虽然AsyncTask到这里已经初始化完毕,但是有一点:执行时的参数mParams还是空的,并没有赋值,在真正调用AsyncTask的execute(...)方法传入参数才进行初始化。
result = doInBackground(mParams);3、AsyncTask执行流程
3.1、执行AsyncTask
execute(Params... params)开始,当然也可以直接调用executeOnExecutor()方法传入指定的执行器。
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
}executeOnExecutor()方法:传入sDefaultExecutor。
①执行前先调用了onPreExecute(),也就是执行前的准备工作。
②同时也初始化mWorker中的mParams参数,前面构造AsyncTask的时候改参数并没有初始化,在执行的时候用到。
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
Params... params) {
if (mStatus != Status.PENDING) {
switch (mStatus) {
case RUNNING:
throw new IllegalStateException("Cannot execute task:"
+ " the task is already running.");
case FINISHED:
throw new IllegalStateException("Cannot execute task:"
+ " the task has already been executed "
+ "(a task can be executed only once)");
}
}
mStatus = Status.RUNNING;
onPreExecute();
mWorker.mParams = params;
exec.execute(mFuture);
return this;
} 注意:这里判断了任务的状态如果已经执行完或者正在执行就会抛出异常。也就是为什么AsyncTask对象创建只能执行一次,如果再次调用,会抛出异常。
/**
* 指示任务的当前状态。 在任务的生命周期内,每个状态只能设置一次。
*/
public enum Status {
/**
* 指示任务尚未执行。
*/
PENDING,
/**
* 表示任务正在运行。
*/
RUNNING,
/**
* 表示onPostExecute已完成。
*/
FINISHED,
}3.2、execute
在指定或者默认的线程池上执行任务,注意在mWorker中的call()方法运行在子线程,所以doInBackground(mParams)运行在子线程执行耗时任务。
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);
Result result = null;
try {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
result = doInBackground(mParams);
Binder.flushPendingCommands();
} catch (Throwable tr) {
mCancelled.set(true);
throw tr;
} finally {
postResult(result);
}
return result;
}
};并且在执行完之后调用postResult。
3.3、结果:onPostExecute(Result result)
子线程中执行完doInBackground(mParams)无论失败成功,finally都会执行将结果post出来。
private Result postResult(Result result) {
@SuppressWarnings("unchecked")
Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(this, result));
message.sendToTarget();
return result;
}在子线程中调用的postResult()通过mHandler切回到主线程执行,更新UI通知结果。
...
case MESSAGE_POST_RESULT:
// There is only one result
result.mTask.finish(result.mData[0]);
break;result就是封装的AsyncTaskResult,传递当前AsyncTask和结果数据,mTask就是当前AsyncTask对象,调用finish()。
private void finish(Result result) {
if (isCancelled()) {
onCancelled(result);
} else {
onPostExecute(result);
}
mStatus = Status.FINISHED;
}运行在主线程中,回调onPostExecute(Result result)并将当前AsyncTask标记为FINISHED。
3.4、更新进度:onProgressUpdate(Progress... values)
在doInbackground()方法中调用publishProgress(Progress... ) 就可以触发onProgressUpdate(Progress... values)方法,在UI线程中执行UI更新等任务。
protected final void publishProgress(Progress... values) {
if (!isCancelled()) {
getHandler().obtainMessage(MESSAGE_POST_PROGRESS,
new AsyncTaskResult<Progress>(this, values)).sendToTarget();
}
}也是通过前面构造函数初始化的mHandler,向主线程发送Message,携带AsyncTask和进度。回到主线程Handler中执行,参考InternalHandler部分源码:
...
case MESSAGE_POST_PROGRESS:
result.mTask.onProgressUpdate(result.mData);
break;在主线程中执行onProgressUpdate(Progress... values)更新执行进度。

