这几天在看一些教程,说到了源码分析的方法,其中之一就是不要纠结于每一行代码到底代表什么,而是要先搞清楚主要流程并学习里面的设计思想。并带着分析了一下 AsyncTask 的源码。分析之后确实感觉受益匪浅,虽然里面一些线程的知识并不了解,但是对整体设计和流程有了一个新的认识。所以为了分享下学到的东西,就记录一边,希望大家也能有所收获。
注意 AsyncTask 在 SDK30 及以上已经被弃用,在开发中并不推荐使用了。
首先,新建一个 AsyncTask 后,实现具体的方法,调用 execute() 方法执行。
之后会调用到这里,可以看到 AsyncTask 是不能够重复调用的,而且 onPreExecute() 会首先调用。
// 1.运行状态初始值是 Status.PENDING
private volatile Status mStatus = Status.PENDING;
@MainThread
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
Params... params) {
if (mStatus != Status.PENDING) {
switch (mStatus) {
case RUNNING:
// 2.如果正在执行,则报错
throw new IllegalStateException("Cannot execute task:"
+ " the task is already running.");
case FINISHED:
// 3.如果已经执行结束,则报错,这里解释了 AsyncTask 不可以重复执行
throw new IllegalStateException("Cannot execute task:"
+ " the task has already been executed "
+ "(a task can be executed only once)");
}
}
// 4.修改状态
mStatus = Status.RUNNING;
// 5.调用 onPreExecute() 方法
onPreExecute();
mWorker.mParams = params;
// 6.在线程池中执行 mFuture
exec.execute(mFuture);
return this;
}
现在来看一下 exec.execute(mFuture); 这里面涉及到线程相关的知识就暂时不讨论,我们只看整体的流程。搜索一下可知 mFuture 是在构造方法中初始化的,代码如下。
public AsyncTask(@Nullable Looper callbackLooper) {
// 1.获取 handler
mHandler = callbackLooper == null || callbackLooper == Looper.getMainLooper()
? getMainHandler()
: new Handler(callbackLooper);
// 4.mWorker 和 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
// 5.执行了 doInBackground 方法,这里已经是在子线程了
result = doInBackground(mParams);
Binder.flushPendingCommands();
} catch (Throwable tr) {
mCancelled.set(true);
throw tr;
} finally {
// 6.将执行结果发送出去
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.这里提供一个 Handler 单例
private static Handler getMainHandler() {
synchronized (AsyncTask.class) {
if (sHandler == null) {
sHandler = new InternalHandler(Looper.getMainLooper());
}
return sHandler;
}
}
// 3.可以看到实现了 Handler 并定义了回调处理方法
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;
}
}
}
// 7.通过 message 发送执行结果,发送后会回调到上方注释 3 处。
private Result postResult(Result result) {
@SuppressWarnings("unchecked")
Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(this, result));
message.sendToTarget();
return result;
}
到这里基本执行流程就完成了,还有一个更新状态的方法其实也是通过发送 message 实现的。
@WorkerThread
protected final void publishProgress(Progress... values) {
if (!isCancelled()) {
getHandler().obtainMessage(MESSAGE_POST_PROGRESS,
new AsyncTaskResult<Progress>(this, values)).sendToTarget();
}
}
简单分析下来,整体流程有了个认识,当然这里面涉及到的一些线程的相关知识还不是了解的很多,但是这并不妨碍我们。
好了文章到这里就结束了,希望对大家有所帮助。