AsyncTask是一个在安卓开发中帮助开发者更简便地创建异步任务的类。先来看简单看一下其用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
new AsyncTask<String,Integer,String>(){

@Override
protected void onPreExecute() {
super.onPreExecute();
}

@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
}

@Override
protected String doInBackground(String... strings) {
return null;
}
}.execute("https://cn.bing.com/");

首先我们来看三个类型参数,第一个Params表示执行任务时传入参数类型,第二个Progress表示后台执行任务更新的进度类型,第三个Result表示后台任务执行结束返回结构的类型。
接下来我们来分析下AsyncTask初始化做了些什么。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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);
}
}
};
}

主要做了三件事,第一创建InternalHandler类型的对象,这个Handler与主线程的looper绑定;第二创建mWorker对象,WorkerRunnable是一个implementsCallable接口的抽象类,这个Callable接口里定义了一个call()方法,可以看到这个重写的call()方法主要执行的就是异步操作,doInBackground(mParams);就在这里被调用;第三步创建FutureTask对象,FutureTask封装了WorkerRunnable中的call()方法。
以调用execute()入口,最后调用的是executeOnExecutor()方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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无法多次执行executed(),如果是等待执行状态,那么将状态改为执行中;第二步执行onPreExecute();,也就是我们执行异步任务之前做的准备,这个方法在我们创建异步任务时可以重写添加自己的处理逻辑;第三步将传入的参数赋值给mWorker中的变量;第四步exec.execute(mFuture);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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);
}
}
}

execSerialExecutor的实例,是AsyncTask中的静态变量,类加载的时候被初始化,被所有实例所共有,它其实是一个双端队列,保存着待执行的任务。ok,mFuture加入队列之后,如果没有正在执行的任务,即调用scheduleNext();

1
2
3
4
5
protected synchronized void scheduleNext() {
if ((mActive = mTasks.poll()) != null) {
THREAD_POOL_EXECUTOR.execute(mActive);
}
}

THREAD_POOL_EXECUTOR是静态代码块创建的一个线程池,这里就是把任务从队列中取出交给线程池执行,最终会调用mWorkercall()方法,doInBackground()执行完返回一个结果最终调用postResult(result);

1
2
3
4
5
6
7
private Result postResult(Result result) {
@SuppressWarnings("unchecked")
Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(this, result));
message.sendToTarget();
return result;
}

getHandler()获取到的是InternalHandler实例,接着看

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
private static class InternalHandler extends Handler {
public InternalHandler(Looper looper) {
super(looper);
}

@SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
@Override
public void handleMessage(Message msg) {
AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj;
switch (msg.what) {
case MESSAGE_POST_RESULT:
// There is only one result
result.mTask.finish(result.mData[0]);
break;
case MESSAGE_POST_PROGRESS:
result.mTask.onProgressUpdate(result.mData);
break;
}
}
}

接着调用AsyncTask中的finish(result.mData[0]);方法

1
2
3
4
5
6
7
8
private void finish(Result result) {
if (isCancelled()) {
onCancelled(result);
} else {
onPostExecute(result);
}
mStatus = Status.FINISHED;
}

最后调用onPostExecute(result);返回执行结果。
我始终还想不明白 Google 工程师设计成串行的目的是为了什么???