AsyncTask源碼分析


要研究Android的AsyncTask之前,要先搞明白FutureTask和Executor類:

 FutureTask是什么:

FutureTask實際上是一個任務的操作類,它並不啟動新線程,只是在自己所在線程上操作,任務的具體實現是構造FutureTask時提供的,實現自Callable<V>接口,FutureTask不知道具體的任務是什么,它只知道如何調度任務,如:

  • 如何啟動任務:在FutureTask的run()方法中(實現自Runnable.run()),調用Callable.call()方法來啟動任務,Callable.call()方法中是任務的具體實現;
  • 如何取消任務:在cancel()里,中斷執行任務的線程,記錄任務結束狀態,並調用done()方法來執行用戶實現的操作;
  • 如何返回任務的運行結果:如果任務還在執行,則阻塞線程(使用LockSupport.park()),直到任務結束才返回結果,用戶可以通過get()方法來獲取結果,同樣當任務運行結束時,會調用down()來執行用戶實現的操作。

使用FutureTask的好處是,更輕松的對任務進行管理,而不是像Runnable那樣扔進線程后就啥也不能做了。

 Executor是什么:

Executor顧名思義是任務執行者,它不關心是什么任務,只關心如何執行任務。Executor是個Interface,具體如何執行任務要看怎么實現這個接口,你可以這樣實現:

 class DirectExecutor implements Executor {
  @Override
public void execute(Runnable r) { r.run(); } }

也可以這樣實現:

class ThreadPerTaskExecutor implements Executor {
  @Override
public void execute(Runnable r) { new Thread(r).start(); } }

這兩種實現的區別顯而易見,java文檔還提供了另一個Executor實現的例子:

 class SerialExecutor implements Executor {
   final Queue tasks = new ArrayDeque();
   final Executor executor;
   Runnable active;

   SerialExecutor(Executor executor) {
     this.executor = executor;
   }
  @Override
public synchronized void execute(final Runnable r) { tasks.offer(new Runnable() { public void run() { try { r.run(); } finally { scheduleNext(); } } }); if (active == null) { scheduleNext(); } } protected synchronized void scheduleNext() { if ((active = tasks.poll()) != null) { executor.execute(active); } } }

這個實現的意思是,嚴格按照用戶提交的順序來執行任務。Android的AsyncTask就使用了這個例子。

AsyncTask是如何實現的:

AsyncTask實現的關鍵地方在構造函數和executeOnExecutor()函數里。

  • 首先看下構造函數:
    public AsyncTask() {
        mWorker = new WorkerRunnable<Params, Result>() {
            public Result call() throws Exception {
                mTaskInvoked.set(true);
                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
          //任務的具體實現
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); } } }; }

 

代碼中WorkerRunnable實現自Callable,所以mWorker就是任務的具體實現(call()中的doInBackground())。通過對FutureTask的說明可以知道,mFuture是mWorker的操作類,它不僅用來實現對AsyncTask任務的操作(cancel,get等),最主要的,實現了mWorker執行結束的操作:

    private void postResultIfNotInvoked(Result result) {
        final boolean wasTaskInvoked = mTaskInvoked.get();
        if (!wasTaskInvoked) {
            postResult(result);
        }
    }

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

    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:
                // 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;
    }

FutureTask和Handler共同實現了任務結束的操作,代碼很簡單,不贅述。

  • 接下來是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)");
            }
        }

        mStatus = Status.RUNNING;

        onPreExecute();

        mWorker.mParams = params;
        exec.execute(mFuture);

        return this;
    }

AsyncTask是通過execute或executeOnExecutor啟動的,通過上邊對Executor的介紹可以知道,在executeOnExecutor()中的exec.execute(mFuture)這一行就是根據exec的實現方式來啟動mFuture了,問題的關鍵是exec是如何實現execute()的。在execute中可以看到AsyncTask提供了一個默認的sDefaultExecutor,這個sDefaultExecutor是什么呢:

    private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;

    public static final Executor SERIAL_EXECUTOR = new SerialExecutor();

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

默認情況下,sDefaultExecutor就是SerialExecutor類,通過源碼可以看到,SerialExecutor是一個嚴格按照用戶提交順序來執行任務的執行者,其中scheduleNext()函數用來啟動下一個任務:

 

        protected synchronized void scheduleNext() {
            if ((mActive = mTasks.poll()) != null) {
                THREAD_POOL_EXECUTOR.execute(mActive);
            }
        }

 

THREAD_POOL_EXECUTOR就是真正啟動任務的Executor:
    public static final Executor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(
            CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS,
            sPoolWorkQueue, sThreadFactory);

ThreadPoolExecutor是java自己實現的一種Executor,顧名思義,是個提供線程池的Executor。

由上可以知道,當調用AsyncTask的execute()函數時,AsyncTask會按用戶提交任務的順序,在線程池里串行的執行任務(當前任務運行結束,再運行下一個)。

當然用戶也可以提供自己的Executor來改變AsyncTask的運行方式。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM