AsyncTask作为官方设计的一种轻量的异步工具类,代码小巧,虽然不同的Android有一些差异问题,在比较新的版本里也标记为Deprecated,现在使用的也比较少了,但是有关异步设计还是很值得学习。具体源码分析是以Android P进行,frameworks\base\core\java\android\os\AsyncTask.java
-
AsyncTask是一个抽象类,使用的时候一般通过子类来创建。在构造的时候会创建了一个处理后台工作的mWorker和关联的任务mFuture。
public abstract class AsyncTask<Params, Progress, Result> { ... private final WorkerRunnable<Params, Result> mWorker; private final FutureTask<Result> mFuture; public AsyncTask() { mWorker = new WorkerRunnable<Params, Result>() { public Result call() throws Exception { mTaskInvoked.set(true); Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); //noinspection unchecked Result result = doInBackground(mParams); Binder.flushPendingCommands(); return postResult(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 static abstract class WorkerRunnable<Params, Result> implements Callable<Result> { Params[] mParams; } }
-
execute()执行流程
@MainThread public final AsyncTask<Params, Progress, Result> execute(Params... params) { return executeOnExecutor(sDefaultExecutor, params); }
从@MainThread注解,可以看出这个方法必须在主线程调用。其中sDefaultExecutor是一个定义为静态内部类Executor的实例,是AsyncTask默认的Executor,并且无法自定义为自己的Executor,代码如下:
public static final Executor SERIAL_EXECUTOR = new SerialExecutor(); private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR; 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); } } } /** @hide */ public static void setDefaultExecutor(Executor exec) { sDefaultExecutor = exec; }
具体executeOnExecutor()代码如下:首先会对当前的运行状态进行检查,如果处于就绪等待运行或者运行完成,会抛出异常。状态没有问题的话,就开始运行,先是执行前准备 onPreExecute(),接着开始上面提到的后台工作mWorker和任务mFuture。
mWorker#中call()执行了**Result result = doInBackground(mParams);**,mWorker执行完成后,mFuture#done()就会通过 postResultIfNotInvoked(get())方法就结果消息发送给Handler。
@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; }
postResultIfNotInvoked()具体代码如下:mTaskInvoked和mCancelled是通过AtomicBoolean一种不加锁机制来保证变量多线程同步,通过变量名称可以看出相应的用途。postResultIfNotInvoked()的作用是将结果封装成AsyncTaskResult通过消息发送给Handler处理
private final AtomicBoolean mCancelled = new AtomicBoolean(); private final AtomicBoolean mTaskInvoked = new AtomicBoolean(); private void postResultIfNotInvoked(Result result) { final boolean wasTaskInvoked = mTaskInvoked.get(); if (!wasTaskInvoked) { 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; } @SuppressWarnings({"RawUseOfParameterizedType"}) private static class AsyncTaskResult<Data> { final AsyncTask mTask; final Data[] mData; AsyncTaskResult(AsyncTask task, Data... data) { mTask = task; mData = data; } }
Handler处理结果:消息为MESSAGE_POST_RESULT时,代表任务执行完成,通过上面的AsyncTaskResult定义,即执行Asynctask#finish()方法,任务执行完成,回调**onPostExecute(result);消息为MESSAGE_POST_PROGRESS时,就回调进度更新**onProgressUpdate()**,相应的这个消息是在我们执行publishProgres()发出。
private static InternalHandler sHandler; ... 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; }
@WorkerThread protected final void publishProgress(Progress... values) { if (!isCancelled()) { getHandler().obtainMessage(MESSAGE_POST_PROGRESS, new AsyncTaskResult<Progress>(this, values)).sendToTarget(); } }
-
总结
-
AsyncTask中在进行耗时操作时,在主线程做一些准备工作,即onPreExecute()
-
AsyncTask中通过mWorker、mFuture、sDefaultExecutor来处理子线程耗时任务,即doInBackground()
-
AsyncTask中通过sHandler来处理任务完成与进度更新回调,即onPostExecute()与onProgressUpdate()
-
AsyncTask中有使用volatile和AtomicBoolean两种机制来保证多线程间变量的同步
-
AsyncTask中三个参数的意义可以看上面过程中参数的传递,各个方法是在子线程还是在主线程执行,可以看@WorkerThread和 @MainThread注解,也可以上面过程。这里就不总结了-_-
-
-
类图与流程图