AsyncTask
AsyncTask, 做 Android 开发都再熟悉不过了. 常规的使用自然不用赘述, 这里主要讲讲 AsyncTask 内部的运行机制. 讲讲我们日常使用时需要实现的那几个抽象方法是如何执行的.
onPreExecute
AsyncTask 的执行从 execute 开始, 我们也以这个方法为入口开始看
- @MainThread
- public final AsyncTask<Params, Progress, Result> execute(Params... params) {
- return executeOnExecutor(sDefaultExecutor, params);
- }
- @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;
- }
onPreExecute() 方法是在 executeOnExecutor 方法内执行.
如代码所示, 当 AsyncTask 正在执行或者已经执行完成后, 调用 execute 方法, 将会抛出异常. 说明一个 AsyncTask 对象只能执行一次, 不能重复执行.
值得注意的是 sDefaultExecutor,AsyncTask 内部实现是由线程池执行异步任务. 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);
- }
- }
- }
- doInBackground
在执行完 onPreExecute() 后, 会调用 sDefaultExecutor 去执行一个 FutureTask 任务. 这个 FutureTask 任务是在 AsyncTask 的构造方法中创建的.
- public AsyncTask() {
- this((Looper) null);
- }
- public AsyncTask(@Nullable Handler handler) {
- this(handler != null ? handler.getLooper() : null);
- }
- 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);
- }
- }
- };
- }
- private static Handler getMainHandler() {
- synchronized (AsyncTask.class) {
- if (sHandler == null) {
- sHandler = new InternalHandler(Looper.getMainLooper());
- }
- return sHandler;
- }
- }
通常我们创建自己的 AsyncTask 对象时, 一般都是不传参数的. 也就是说我们的 AsyncTask 对象, 会用 UI 主线程的 Looper 对象, 创建一个 Handler 对象, 用于子线程和主线程之间的切换.
接下来会创建一个 WorkerRunnable 对象, 它实现了 Callable 接口, 在 call() 方法中, 执行 doInBackground 方法.
然后将这个 WorkerRunnable 对象封装成 FutureTask 对象, 构造成一个可执行的任务. 由 sDefaultExecutor 执行. 这也是 doInBackground 方法在子线程中执行的运行机制.
onPostExecute
mWorker 对象的 call() 方法执行到最后, 会调用 postResult 方法并将 doInBackground 方法的执行结果传进去. 而如果 mFuture 任务执行完成或者任务被取消, 其在 done() 方法中, 会执行 postResultIfNotInvoked 方法, 这个方法会根据标识位 mTaskInvoked 判断, 是否需要调用 postResult 方法. mTaskInvoked 标识位的作用是在 mFuture 任务开始执行后, 防止 postResult 方法被重复调用.
- 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;
- }
- private Handler getHandler() {
- return mHandler;
- }
然后我们看到, postResult 方法中, 发送了一个 Message 给 mHandler 对象. 这个 Message 中包含 doInBackground 方法的返回值 AsyncTaskResult, 和 MESSAGE_POST_RESULT 标识.
一般情况下, mHandler, 也就是 getMainHandler 方法中创建的 InternalHandler 对象. 它的 Looper 也就是主线程的 Looper.
- 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;
- }
- }
- }
- private static class AsyncTaskResult<Data> {
- final AsyncTask mTask;
- final Data[] mData;
- AsyncTaskResult(AsyncTask task, Data... data) {
- mTask = task;
- mData = data;
- }
- }
在 InternalHandler 的 handleMessage 的 handleMessage 方法中我们可以看到, 当标识为 MESSAGE_POST_RESULT 时, 它会执行 mTask.finish 方法. 这个 mTask, 就是 postResult 方法中创建 AsyncTaskResult 对象时的 this, 也就是这个 AsyncTask 对象本身.
所以 MESSAGE_POST_RESULT 的处理, 也就是调用 AsyncTask 的 finish 方法.
- private void finish(Result result) {
- if (isCancelled()) {
- onCancelled(result);
- } else {
- onPostExecute(result);
- }
- mStatus = Status.FINISHED;
- }
最后我们看到了, onPostExecute 方法是在 AsyncTask 的 finish 方法内调用.
onProgressUpdate
关于 onProgressUpdate, 其实也是通过 mHandler 来处理. 我们都知道, 触发 onProgressUpdate 需要在 doInBackground 方法中调用 publishProgress 方法, 来触发更新. 而在 publishProgress 方法内, 也是通过给 mHandler 发送标识为 MESSAGE_POST_PROGRESS 的 Message 来实现的.
- @WorkerThread
- protected final void publishProgress(Progress... values) {
- if (!isCancelled()) {
- getHandler().obtainMessage(MESSAGE_POST_PROGRESS,
- new AsyncTaskResult<Progress>(this, values)).sendToTarget();
- }
- }
到此, 这就是 AsyncTask 基本的运行机制.
来源: http://www.jianshu.com/p/6852e22e953e