Android:AsyncTask源碼解讀
標題黨
AsyncTask源碼解讀,解讀這么流弊的標題,嚇得我都不敢寫下去啦!菜鳥一枚,寫不對的地方,請各位大神在留下評論或拍磚,我會為大家貢獻更多多的妹子圖。

PS妹子圖鎮樓,可以增加閱讀量
AsyncTask簡單使用
-
直接上代碼,很簡單就是在子線程中結算1到100的和。妹子你走開,我要開始擼代碼啦!
public static void main(String arg[]) throws InterruptedException { MyTask task = new MyTask(); task.execute(100); } static class MyTask extends AsyncTask<Integer, Integer, Integer> { @Override protected void onPreExecute() { System.out.println("onPreExecute"); super.onPreExecute(); } @Override protected void onProgressUpdate(Integer... values) { System.out.println("onProgressUpdate " + values[0]); super.onProgressUpdate(values); } @Override protected Integer doInBackground(Integer... integers) { //在新的線程中執行 int sum = 0; for (int i = 0; i < integers[0]; i++) { sum = sum + i; publishProgress(i);//給InternalHandler發送進度更新的消息 } return sum; }@Override protected void onPostExecute(Integer integer) { //將子線程的結果post到主線程 super.onPostExecute(integer); }}</code></pre> </li>
稍微介紹重要的幾個方法;暫時忘記到妹子圖吧!看看以下四個方法:@MainThread表示在主線程中執行,而@WorkerThread表示在子線程中執行
@MainThread protected void onPreExecute() @MainThread protected void onPostExecute(Result result) @MainThread protected void onProgressUpdate(Progress... values) @WorkerThread protected abstract Result doInBackground(Params... params)-
onPreExecute:表示該方法是運行在主線程中的。在AsyncTask執行了execute()方法后就會在UI線程上執行onPreExecute()方法,該方法在task真正執行前運行,我們通常可以在該方法中顯示一個進度條,從而告知用戶后臺任務即將開始。
-
doInBackground :表示該方法是運行在單獨的工作線程中的,而不是運行在主線程中。doInBackground會在onPreExecute()方法執行完成后立即執行,該方法用于在工作線程中執行耗時任務,我們可以在該方法中編寫我們需要在后臺線程中運行的邏輯代碼,由于是運行在工作線程中,所以該方法不會阻塞UI線程。該方法接收Params泛型參數,參數params是Params類型的不定長數組,該方法的返回值是Result泛型,由于doInBackgroud是抽象方法,我們在使用AsyncTask時必須重寫該方法。在doInBackground中執行的任務可能要分解為好多步驟,每完成一步我們就可以通過調用AsyncTask的publishProgress(Progress…)將階段性的處理結果發布出去,階段性處理結果是Progress泛型類型。當調用了publishProgress方法后,處理結果會被傳遞到UI線程中,并在UI線程中回調onProgressUpdate方法,下面會詳細介紹。根據我們的具體需要,我們可以在doInBackground中不調用publishProgress方法,當然也可以在該方法中多次調用publishProgress方法。doInBackgroud方法的返回值表示后臺線程完成任務之后的結果。
-
onProgressUpdate 上面我們知道,當我們在doInBackground中調用publishProgress(Progress…)方法后,就會在UI線程上回調onProgressUpdate方法
注解,表示該方法是在主線程上被調用的,且傳入的參數是Progress泛型定義的不定長數組。如果在doInBackground中多次調用了publishProgress方法,那么主線程就會多次回調onProgressUpdate方法。
-
onPostExecute :表示該方法是在主線程中被調用的。當doInBackgroud方法執行完畢后,就表示任務完成了,doInBackgroud方法的返回值就會作為參數在主線程中傳入到onPostExecute方法中,這樣就可以在主線程中根據任務的執行結果更新UI。
</ul> </li>
</ol>
-
AsyncTask的三個狀態
public enum Status { /*** Indicates that the task has not been executed yet. * 還沒有執行 */ PENDING, /** * Indicates that the task is running. * 正在執行 */ RUNNING, /** * Indicates that {@link AsyncTask#onPostExecute} has finished. * 執行結束 */ FINISHED,}</code></pre> </li>
子線程與主線程通訊:(handle)
private static class InternalHandler extends Handler { public InternalHandler() { super(Looper.getMainLooper()); }@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]);//調用onPostExecute 將結果post到主線程 break; case MESSAGE_POST_PROGRESS://調用onProgressUpdate更新進度 result.mTask.onProgressUpdate(result.mData); break; } }} private void finish(Result result) { if (isCancelled()) { onCancelled(result); } else { onPostExecute(result); } mStatus = Status.FINISHED; }</code></pre> </li>
構造函數
public AsyncTask() { mWorker = new WorkerRunnable<Params, Result>() { public Result call() throws Exception { mTaskInvoked.set(true); Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); //noinspection unchecked Result result = doInBackground(mParams);//調用doInBackground 在子線程中做一系列的事情 Binder.flushPendingCommands(); return postResult(result);//給InternalHandler發送一個doInBackground任務執行完成的消息 } };mFuture = new FutureTask<Result>(mWorker) { @Override protected void done() { try { postResultIfNotInvoked(get());//等待mWorker的call方法執行完成 } 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);//如果doInBackground發生異常,則向主線程發送一個null的結果 } } };}</code></pre> </li>
execute(params)最終調用executeOnExecutor
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();//在主線程總調用onPreExecute mWorker.mParams = params;//mWorker 設置參數 exec.execute(mFuture);//線程池執行futureTask return this; }- AsyncTask執行一個task的流程圖
</ol>
流程圖1

流程圖2

流程圖3

流程圖4
來自:http://www.jianshu.com/p/589358898780
內部實現
上面講了那么多,然而都不是重點,現在才剛開始進入主題。AsyncTask其實就是用線程池和和handle實現的!