AsyncTask源码分析及工作原理

102 阅读3分钟

1. 任务执行流程

execute方法中会调用executeOnExecutor方法:

   public final AsyncTask<Params, Progress, Result> execute(Params... params) {
       return executeOnExecutor(sDefaultExecutor, params);
   }

   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)");
           }
       }

       // 设置任务状态为RUNNING
       mStatus = Status.RUNNING;

       // 在主线程中调用onPreExecute()方法进行初始化工作
       onPreExecute();

       // 将传递给任务的参数存储在mWorker的mParams属性中
       mWorker.mParams = params;

       // 通过exec.execute(mFuture)方法将任务提交给指定的执行器
       exec.execute(mFuture);

       return this;
   }

executeOnExecutor方法中,任务首先会被提交给一个Executor来执行。默认情况下,使用的是SerialExecutor,它保证任务按顺序执行。

2. SerialExecutor的执行过程

   private static class SerialExecutor implements Executor {
       final ArrayDeque<Runnable> mTasks = new ArrayDeque<>();
       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来执行任务
               THREAD_POOL_EXECUTOR.execute(mActive);
           }
       }
   }

AsyncTask中有两个线程池,其中线程池SerialExecutor用于任务的排队,而线程池THREAD_POOL_EXECUTOR用于真正的执行任务。

SerialExecutor的execute方法将任务添加到任务队列中,然后调用scheduleNext方法取出任务并执行。

scheduleNext方法从任务队列中取出任务,然后调用THREAD_POOL_EXECUTOR的execute方法来执行任务,最终会执行mFuture的run方法。

3. 任务执行

mWorker = new WorkerRunnable<Params, Result>() {
    public Result call() throws Exception {
        mTaskInvoked.set(true);
        Result result = null;
        try {
            // 设置后台线程的优先级
            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
            // 执行后台任务
            result = doInBackground(mParams);
            // 刷新Binder中挂起的命令
            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);
        }
    }
};

在FutureTask的run方法中会调用mWorker的call方法,mWorker的call方法会调用doInBackground方法,最后将其返回值传递给postResult方法。

4. 处理任务结果

   private Result postResult(Result result) {
       @SuppressWarnings("unchecked")
       Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
               new AsyncTaskResult<Result>(this, result));
       message.sendToTarget();
       return result;
   }

postResult()方法通过Handler发送一个消息来处理任务结果。消息在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:
                   // 处理任务执行完成后的结果
                   result.mTask.finish(result.mData[0]);
                   break;
               case MESSAGE_POST_PROGRESS:
                   result.mTask.onProgressUpdate(result.mData);
                   break;
           }
       }
   }

handleMessage()方法中,根据消息类型调用finish()方法处理任务的执行结果。

5. 任务完成

   private void finish(Result result) {
       // 如果任务被取消,则调用onCancelled()
       if (isCancelled()) {
           onCancelled(result);
       } else {
           // 否则调用onPostExecute()
           onPostExecute(result);
       }
       // 设置任务状态为FINISHED
       mStatus = Status.FINISHED;
   }

finish()方法中,根据任务是否被取消调用onCancelled()或者onPostExecute()方法来处理任务的最终结果。

总结

通过以上分析,可以清楚地了解到AsyncTask的工作原理。它使用了SerialExecutor来保证任务的顺序执行,而真正的任务执行是由THREAD_POOL_EXECUTOR来处理的。任务执行完毕后,会通过Handler来发送消息,从而在主线程中处理任务的结果,最终调用相应的回调方法来完成整个任务的生命周期。