AsynckTask的執行原理

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,:)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章