AsyncTask 異步執行
AsyncTask 中持有了靜態的 InternalHandler (初始化時默認綁定 MainLooper),靜態的串行執行任務的線程池和靜態的并行執行任務的線程池
但是串行執行任務的線程池并不會自己處理任務,而是調用并行線程池處理任務。執行任務時將任務添加到串行線程池中的 mTask 隊列中,隊列中會依次取出任務并調用并行線程池來執行任務,在傳遞任務時通過 WorkderRunnable 和 FutureTask 將參數傳遞到并行線程池,并行線程池中處理任務時調用 doInBackground 方法,該方法執行在子線程。
并行線程池每執行完一個任務, 都會通過 InternalHandler 發送消息,InternalHandler 處理消息在主線程,收到執行完成消息后,做完成處理(消息中持有當前 AsyncTask 對象的引用,調用該引用完成操作)。
執行結束后串行線程池會從隊列中再取出一個任務,如果沒有任務則不處理,有任務則繼續調用并行線程池處理,所以串行線程池中通過 mTask 隊列完成串行執行。
執行流程分析
AsyncTask
InternalHandler
構造函數中默認綁定 MainLooper ,其處理消息在主線程
SerialExecutor sDefaultExecutor 串行執行任務的線程池
Executor THREAD_POOL_EXECUTOR 并行執行任務的線程池
AsyncTask 初始化時,初始化 FutureTask 對象,為一個 Runnable,其保持了 WorkerRunnable 對象的引用,WorkerRunnable 中持有任務參數。
excute 方法中,調用了 ExcuteOnExecutor 方法, 將 SerialExecutor 作為默認線程池處理 FutureTask 任務
ExcuteOnExecutor 會先判斷當前異步任務的狀態,如果在運行或結束則拋出異常,無異常則修改 AsyncTask 的狀態并執行 onPreExcute 方法,接著調用 SerialExecutor 的 execute 方法
SerialExecutor 的 execute 方法將任務添加到其內部的隊列 mTasks 中,按順序依次執行
SerialExecutor 中執行任務時,調用 THREAD_POOL_EXECUTOR 處理任務,執行完畢后再從 mTasks 中取下一個任務,從而實現串行
執行任務時在子線程中,調用被執行的 FutureTask 的 run 方法,其中調用其保持的 WorkerRunnable 對象的 call 方法
call 方法中,會調用 doInBackground 方法從而該方法中的代碼執行在子線程,調用 publishProgress 方法通過 InternalHandler 消息機制向主線程發送進度
call 方法中 doInBackground 執行結束后,調用 postResult 方法,通過消息機制,調用 AsyncTask 的 finish 方法
finish 方法中判斷如果任務取消則調用 onCancelled 如果未取消則調用 onPostExecute ,最后更新任務的狀態
總結
1.6 版本之前串行處理,1.6之后并行處理,3.0之后再次改為串行處理,想要并行執行,直接調用 executeOnExecutor 方法,參數傳入 AsyncTask 的靜態屬性 THREAD_POOL_EXECTOR 線程池。
創建 AsyncTask 類對象,調用 execute 方法啟動,默認啟動的是順序執行的,執行過程中線程的切換是通過靜態的 InternalHandler 完成的
InternalHandler 創建時自動綁定 MainLooper ,所以處理事件運行在主線程
AsyncTask 實例化時,會創建創建 WorkerRunnable 對象和 FutureTask 對象,在線程池中的線程運行時會在 FutureTask 的 run 方法中調用 WorkerRunnable 的 call 方法,call 方法就運行在了子線程,call方法中調用 doInBackground 方法也就運行在了子線程
doInBackground 執行結束之后會使用 InternalHandler 發消息將當前 AsyncTask 和 返回值傳遞到主線程
主線程處理消息時調用對應 AsyncTask 的 finish 方法,處理 onCanclelled 和 onPostExecute 方法
子線程運行過程中的進度提交也是通過類似方式,在 doInBackground 中調用 publishProgress 方法,該方法會將進度使用 InternalHandler 提交
主線程收到 InternalHandler 發來的進度之后,通過 onProgressUpdata 接收進度并做相應處理
運行時首先調用 opRreExecute 方法,再通過 Executor 的 excute 方法,將包裝了 WorkerRunnable 這個 Runnable 對象的 FutureTask 對象傳入線程池,線程池中就會調用 FutureTask 的 run 方法,run 方法中調用 WorkerRunnable 的 call 方法,call 再執行 doInBackGround 方法,最后通過 Handler 提交到主線程執行 onPostExcuete 方法