本文分析的源码来自于API-25所以与之前版本的AsyncTask源码有所区别。
1、必须在uithread 创建 AsyncTask 对象
/**
* Creates a new asynchronous task. This constructor must be invoked on the UI thread.
*/
public AsyncTask() {
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);
}
}
};
}
private void postResultIfNotInvoked(Result result) {
final boolean wasTaskInvoked = mTaskInvoked.get();
if (!wasTaskInvoked) {
postResult(result);
}
}
构造函数里面 初始化了WorkerRunnable(实现了Callable接口)和FutureTask对象。
2、AsyncTask 提供了两个对外的执行方法。
2.1
@MainThread
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
}
从代码可以看到,该方法调用了executeOnExecutor(sDefaultExecutor, params); sDefaultExecutor是默认的线程池实现。代码如下:
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);
}
}
}
该类里面维护了一个Runnable栈,Runnable顺序执行,所以如果调用 execute(Params... params)方法是进行顺序执行任务。
2.2
@MainThread
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;
}
其实 execute(Params... params)调用的就是这个方法。只不过传入了默认的顺序执行任务的线程池实现。
调用该方法时,可以传入默认的线程池实现,也可以传入已经THREAD_POOL_EXECUTOR。
如果想要并发执行任务,就可以调用次方法,传入THREAD_POOL_EXECUTOR,注意处理好并发的问题。
2.2.1
从 executeOnExecutor()方法的代码可以看到,用调用了onPreExecute()方法。由于executeOnExecutor方法在主线程执行,所以onPreExecute()方法也在主线程执行。
当执行到 exec.execute(mFuture)时,mFuture被调用。这时我们可以回到mFuture和mWorker的初始化看一下具体的逻辑代码。
在mWorker初始化的类中,重载的call()方法中调用了 result = doInBackground(mParams); 由于 doInBackground 在工作线程被调用,所以 doInBackground方法里面可以处理耗时的操作,但不可以直接更新UI。
result = doInBackground(mParams); 获取result之类,把结果传递给了 postResult(result);
private Result postResult(Result result) {
@SuppressWarnings("unchecked")
Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(this, result));
message.sendToTarget();
return result;
}
2.2.2
private static class InternalHandler extends Handler {
public InternalHandler() {
super(Looper.getMainLooper());
}
@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;
}
}
}
private void finish(Result result) {
if (isCancelled()) {
onCancelled(result);
} else {
onPostExecute(result);
}
mStatus = Status.FINISHED;
}
InternalHandler继承了Handler 通过 super(Looper.getMainLooper()) 绑定到了主线程。在handleMessage中处理postResult(result)传来的结果result,把result传递给了AsyncTask类的 finish()方法,finish()方法调用了onPostExecute()方法,由于InternalHandler绑定到了主线程上,所以onPostExecute()方法执行在主线程。
本文分析的源码来自于API-25所以与之前版本的AsyncTask源码有所区别。具体什么区别请看别人的文章: 传送门