AsyncTask 異步執(zhí)行
AsyncTask 中持有了靜態(tài)的 InternalHandler (初始化時(shí)默認(rèn)綁定 MainLooper)农尖,靜態(tài)的串行執(zhí)行任務(wù)的線程池和靜態(tài)的并行執(zhí)行任務(wù)的線程池
但是串行執(zhí)行任務(wù)的線程池并不會(huì)自己處理任務(wù),而是調(diào)用并行線程池處理任務(wù)瓷翻。執(zhí)行任務(wù)時(shí)將任務(wù)添加到串行線程池中的 mTask 隊(duì)列中缺虐,隊(duì)列中會(huì)依次取出任務(wù)并調(diào)用并行線程池來(lái)執(zhí)行任務(wù),在傳遞任務(wù)時(shí)通過(guò) WorkderRunnable 和 FutureTask 將參數(shù)傳遞到并行線程池功茴,并行線程池中處理任務(wù)時(shí)調(diào)用 doInBackground 方法庐冯,該方法執(zhí)行在子線程。
并行線程池每執(zhí)行完一個(gè)任務(wù)坎穿, 都會(huì)通過(guò) InternalHandler 發(fā)送消息展父,InternalHandler 處理消息在主線程返劲,收到執(zhí)行完成消息后,做完成處理(消息中持有當(dāng)前 AsyncTask 對(duì)象的引用栖茉,調(diào)用該引用完成操作)篮绿。
執(zhí)行結(jié)束后串行線程池會(huì)從隊(duì)列中再取出一個(gè)任務(wù),如果沒(méi)有任務(wù)則不處理吕漂,有任務(wù)則繼續(xù)調(diào)用并行線程池處理亲配,所以串行線程池中通過(guò) mTask 隊(duì)列完成串行執(zhí)行。
執(zhí)行流程分析
AsyncTask
InternalHandler
構(gòu)造函數(shù)中默認(rèn)綁定 MainLooper 惶凝,其處理消息在主線程
SerialExecutor sDefaultExecutor 串行執(zhí)行任務(wù)的線程池
Executor THREAD_POOL_EXECUTOR 并行執(zhí)行任務(wù)的線程池
AsyncTask 初始化時(shí)弃榨,初始化 FutureTask 對(duì)象,為一個(gè) Runnable梨睁,其保持了 WorkerRunnable 對(duì)象的引用鲸睛,WorkerRunnable 中持有任務(wù)參數(shù)。
excute 方法中坡贺,調(diào)用了 ExcuteOnExecutor 方法官辈, 將 SerialExecutor 作為默認(rèn)線程池處理 FutureTask 任務(wù)
ExcuteOnExecutor 會(huì)先判斷當(dāng)前異步任務(wù)的狀態(tài),如果在運(yùn)行或結(jié)束則拋出異常遍坟,無(wú)異常則修改 AsyncTask 的狀態(tài)并執(zhí)行 onPreExcute 方法拳亿,接著調(diào)用 SerialExecutor 的 execute 方法
SerialExecutor 的 execute 方法將任務(wù)添加到其內(nèi)部的隊(duì)列 mTasks 中,按順序依次執(zhí)行
SerialExecutor 中執(zhí)行任務(wù)時(shí)愿伴,調(diào)用 THREAD_POOL_EXECUTOR 處理任務(wù)肺魁,執(zhí)行完畢后再?gòu)?mTasks 中取下一個(gè)任務(wù),從而實(shí)現(xiàn)串行
執(zhí)行任務(wù)時(shí)在子線程中隔节,調(diào)用被執(zhí)行的 FutureTask 的 run 方法鹅经,其中調(diào)用其保持的 WorkerRunnable 對(duì)象的 call 方法
call 方法中,會(huì)調(diào)用 doInBackground 方法從而該方法中的代碼執(zhí)行在子線程怎诫,調(diào)用 publishProgress 方法通過(guò) InternalHandler 消息機(jī)制向主線程發(fā)送進(jìn)度
call 方法中 doInBackground 執(zhí)行結(jié)束后瘾晃,調(diào)用 postResult 方法,通過(guò)消息機(jī)制,調(diào)用 AsyncTask 的 finish 方法
finish 方法中判斷如果任務(wù)取消則調(diào)用 onCancelled 如果未取消則調(diào)用 onPostExecute 幻妓,最后更新任務(wù)的狀態(tài)
總結(jié)
1.6 版本之前串行處理蹦误,1.6之后并行處理,3.0之后再次改為串行處理肉津,想要并行執(zhí)行强胰,直接調(diào)用 executeOnExecutor 方法,參數(shù)傳入 AsyncTask 的靜態(tài)屬性 THREAD_POOL_EXECTOR 線程池妹沙。
創(chuàng)建 AsyncTask 類對(duì)象偶洋,調(diào)用 execute 方法啟動(dòng),默認(rèn)啟動(dòng)的是順序執(zhí)行的初烘,執(zhí)行過(guò)程中線程的切換是通過(guò)靜態(tài)的 InternalHandler 完成的
InternalHandler 創(chuàng)建時(shí)自動(dòng)綁定 MainLooper 涡真,所以處理事件運(yùn)行在主線程
AsyncTask 實(shí)例化時(shí),會(huì)創(chuàng)建創(chuàng)建 WorkerRunnable 對(duì)象和 FutureTask 對(duì)象肾筐,在線程池中的線程運(yùn)行時(shí)會(huì)在 FutureTask 的 run 方法中調(diào)用 WorkerRunnable 的 call 方法哆料,call 方法就運(yùn)行在了子線程,call方法中調(diào)用 doInBackground 方法也就運(yùn)行在了子線程
doInBackground 執(zhí)行結(jié)束之后會(huì)使用 InternalHandler 發(fā)消息將當(dāng)前 AsyncTask 和 返回值傳遞到主線程
主線程處理消息時(shí)調(diào)用對(duì)應(yīng) AsyncTask 的 finish 方法吗铐,處理 onCanclelled 和 onPostExecute 方法
子線程運(yùn)行過(guò)程中的進(jìn)度提交也是通過(guò)類似方式东亦,在 doInBackground 中調(diào)用 publishProgress 方法,該方法會(huì)將進(jìn)度使用 InternalHandler 提交
主線程收到 InternalHandler 發(fā)來(lái)的進(jìn)度之后唬渗,通過(guò) onProgressUpdata 接收進(jìn)度并做相應(yīng)處理
運(yùn)行時(shí)首先調(diào)用 opRreExecute 方法典阵,再通過(guò) Executor 的 excute 方法,將包裝了 WorkerRunnable 這個(gè) Runnable 對(duì)象的 FutureTask 對(duì)象傳入線程池镊逝,線程池中就會(huì)調(diào)用 FutureTask 的 run 方法,run 方法中調(diào)用 WorkerRunnable 的 call 方法壮啊,call 再執(zhí)行 doInBackGround 方法,最后通過(guò) Handler 提交到主線程執(zhí)行 onPostExcuete 方法