Android中处理耗时操作时,我们常常使用AsynckTask来处理,那AsynckTask的是怎样执行的呢?我们探究一下源码。
一、AsynckTask的主要的四个方法
- onPreExecute()任务执行开始前,主线程中
- doInBackground()AsynckTask的抽象方法,任务执行中,在子线各执行
- onProgressUpdate()执行中,主线程中
- onPostExecute()执行完成,在主线程中
二、探究源码
AsynckTask的执行起点是execute方法,
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
}
上面的sDefaultExecutor是一个线程池,在类新建的时候初始化,相关代码
//线程池
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
//execute方法中sDefaultExecutor
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
private static class SerialExecutor implements Executor {
final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
Runnable mActive;
//r为下文中的mFuture
public synchronized void execute(final Runnable r) {
//可以理解为任务的调度
mTasks.offer(new Runnable() {
public void run() {
try {
r.run();
} finally {
scheduleNext();
}
}
});
if (mActive == null) {
scheduleNext();
}
}
//任务真正执行的地方,mWorker是在THREAD_POOL_EXECUTOR线程池中执行的
protected synchronized void scheduleNext() {
if ((mActive = mTasks.poll()) != null) {
THREAD_POOL_EXECUTOR.execute(mActive);
}
}
}
接下来进行到executeOnExecutor方法中,这个方法的源码如下:
//判断此任务的状态,如果不是初始状态,抛出异常,这也是异步任务在执行过程中,不能重复执行的原因,一个异常任务只能执行一次,想再次执行得再new
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,主线程中
onPreExecute();
//参数传递
mWorker.mParams = params;
//放在上文中的sDefaultExecutor去执行下一步
exec.execute(mFuture);
return this;
上面的方法,mWorker与mFuture是什么呢?这两个是在异步任务创建时,初始化的
public AsyncTask() {
//任务执行线程
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
//AtomicBoolean标志位,设置为true,
mTaskInvoked.set(true); Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//参数传递并在子类执行doInBackground方法,此方法必须执行
return postResult(doInBackground(mParams));
}
};
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 occured while executing doInBackground()",
e.getCause());
} catch (CancellationException e) {
postResultIfNotInvoked(null);
}
}
};
}
//判断mWorker的状态,如果mTaskInvoked.get()为false,表示doInBackground方法已执行完
private void postResultIfNotInvoked(Result result) {
final boolean wasTaskInvoked = mTaskInvoked.get();
if (!wasTaskInvoked) {
postResult(result);
}
}
//如果执行完,使用Handler发送信息到主线程进行下一步处理
private Result postResult(Result result) {
@SuppressWarnings("unchecked")
Message message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(this, result));
message.sendToTarget();
return result;
}
下面来看一下sHandler,进行消息的处理
//初始化
private static final InternalHandler sHandler = new InternalHandler();
//实体类
private static class InternalHandler extends Handler {
@SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
@Override
//消息处理
public void handleMessage(Message msg) {
AsyncTaskResult result = (AsyncTaskResult) msg.obj;
switch (msg.what) {
case MESSAGE_POST_RESULT:
// 执行fisish方法,如果任务没有被取消,将会执行onPostExecute,并返回数据
result.mTask.finish(result.mData[0]);
break;
case MESSAGE_POST_PROGRESS:
// onProgressUpdate方法执行 result.mTask.onProgressUpdate(result.mData);
break;
}
}
}
那onProgressUpdate会在什么时候执行呢,当我们调用下面方法将会执行
protected final void publishProgress(Progress... values) {
//如果任务没有取消,发送消息
if (!isCancelled()) {
sHandler.obtainMessage(MESSAGE_POST_PROGRESS,
new AsyncTaskResult<Progress>(this, values)).sendToTarget();
}
}
后记:大部分的注释解析已写到代码中。可能组织的不好,希望请见谅。Thanks,:)