Android:AsyncTask源碼解析

來源:互聯網
上載者:User

標籤:asynctask   源碼   

簡例
private class MyAsyncTask extends AsyncTask<String,Void,String>{    @Override    protected String doInBackground(String... params) {        String str = params[0];        return "disposed " + str;    }    @Override    protected void onPostExecute(String s) {        Log.e("TAG", s);        super.onPostExecute(s);    }}
new MyAsyncTask().execute("leelit");
內部邏輯

1、執行個體化AsyncTask,new MyAsyncTask();

public AsyncTask() {        mWorker = new WorkerRunnable<Params, Result>() {            public Result call() throws Exception {                mTaskInvoked.set(true);                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);                //noinspection unchecked                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對象實現了Callable< result>,mFuture在這裡可以看作是對mWorker的一次封裝,他是一個FutureTask對象。

2、myAsyncTask.execute(params)

    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;    }
    private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;

execute方法直接調用executeOnExecutor方法,在這個方法內部:

  • 首先進行狀態的判斷和設定,這裡也說明一個AsyncTask對象只能execute一次,否則拋出異常;
  • 然後執行一個onPreExecute()方法,這也是我們可以重寫的執行流程的第一個執行方法;
  • 設定mWorker參數;
  • 線程池執行任務。

注意,這裡的exec傳遞進來的是sDefaultExecutor,而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);            }        }    }

上面這段代碼還是比較好明白的,就是串列執行任務的實現。裡面的線程池THREAD_POOL_EXECUTOR,各個版本也會有所不同,不過大多數任務隊列都設在了128。

    private static final int CORE_POOL_SIZE = CPU_COUNT + 1;    private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;    private static final int KEEP_ALIVE = 1;    private static final BlockingQueue<Runnable> sPoolWorkQueue =            new LinkedBlockingQueue<Runnable>(128);      public static final Executor THREAD_POOL_EXECUTOR            = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,                    TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
執行全過程

1、執行個體化MyAsyncTask對象,執行個體化mWorker對象和mFuture對象。
2、調用execute方法,判斷設定狀態,執行可選擇重寫的onPreExecute();方法,設定參數,內部線程池執行任務,exec.execute(mFuture)。
3、執行mWorker裡面的任務,調用doInBackground(mParams)方法,這也是必須重寫的,
4、執行postResult方法,將訊息發回主線程,postResult(doInBackground(mParams));

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

5、Handler處理訊息,這裡輾轉到最後就會調用重寫的需要在主線程處理的 onPostExecute(result);方法

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

另外一個常用的方法是publishProgress,它也是通過Handler發送一個訊息給主線程去處理

getHandler().obtainMessage(MESSAGE_POST_PROGRESS,                    new AsyncTaskResult<Progress>(this, values)).sendToTarget();
小結

1、每個AsyncTask對象只能執行一次任務,因為其內部會有狀態判斷和設定;
2、內部共用一個線程池,任務隊列為128,串列順序執行任務,不過最後效果還是會看具體的線程池。
3、執行個體化AsyncTask對象,建構函式就是執行個體化一個 FutureTask對象,一旦運行就執行給定的 Callable。 這裡的Callable對象就是mWorker,其內部是執行doInBackground(mParams)方法,這也是必須重寫的,最後執行postResult方法,通過Handler將訊息發回主線程,postResult(doInBackground(mParams))。

執行個體化AsyncTask對象,就是執行個體化任務對象,這個任務內部調用重寫的方法;
調用執行方法就是線程池去執行任務,最後通過Handler來完成非同步通訊。

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

Android:AsyncTask源碼解析

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.