AsyncTask 源碼解析

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ù)的線程池

  1. AsyncTask 初始化時(shí)弃榨,初始化 FutureTask 對(duì)象,為一個(gè) Runnable梨睁,其保持了 WorkerRunnable 對(duì)象的引用鲸睛,WorkerRunnable 中持有任務(wù)參數(shù)。

  2. excute 方法中坡贺,調(diào)用了 ExcuteOnExecutor 方法官辈, 將 SerialExecutor 作為默認(rèn)線程池處理 FutureTask 任務(wù)

  3. ExcuteOnExecutor 會(huì)先判斷當(dāng)前異步任務(wù)的狀態(tài),如果在運(yùn)行或結(jié)束則拋出異常遍坟,無(wú)異常則修改 AsyncTask 的狀態(tài)并執(zhí)行 onPreExcute 方法拳亿,接著調(diào)用 SerialExecutor 的 execute 方法

  4. SerialExecutor 的 execute 方法將任務(wù)添加到其內(nèi)部的隊(duì)列 mTasks 中,按順序依次執(zhí)行

  5. SerialExecutor 中執(zhí)行任務(wù)時(shí)愿伴,調(diào)用 THREAD_POOL_EXECUTOR 處理任務(wù)肺魁,執(zhí)行完畢后再?gòu)?mTasks 中取下一個(gè)任務(wù),從而實(shí)現(xiàn)串行

  6. 執(zhí)行任務(wù)時(shí)在子線程中隔节,調(diào)用被執(zhí)行的 FutureTask 的 run 方法鹅经,其中調(diào)用其保持的 WorkerRunnable 對(duì)象的 call 方法

  7. call 方法中,會(huì)調(diào)用 doInBackground 方法從而該方法中的代碼執(zhí)行在子線程怎诫,調(diào)用 publishProgress 方法通過(guò) InternalHandler 消息機(jī)制向主線程發(fā)送進(jìn)度

  8. call 方法中 doInBackground 執(zhí)行結(jié)束后瘾晃,調(diào)用 postResult 方法,通過(guò)消息機(jī)制,調(diào)用 AsyncTask 的 finish 方法

  9. finish 方法中判斷如果任務(wù)取消則調(diào)用 onCancelled 如果未取消則調(diào)用 onPostExecute 幻妓,最后更新任務(wù)的狀態(tài)

總結(jié)

  1. 1.6 版本之前串行處理蹦误,1.6之后并行處理,3.0之后再次改為串行處理肉津,想要并行執(zhí)行强胰,直接調(diào)用 executeOnExecutor 方法,參數(shù)傳入 AsyncTask 的靜態(tài)屬性 THREAD_POOL_EXECTOR 線程池妹沙。

  2. 創(chuàng)建 AsyncTask 類對(duì)象偶洋,調(diào)用 execute 方法啟動(dòng),默認(rèn)啟動(dòng)的是順序執(zhí)行的初烘,執(zhí)行過(guò)程中線程的切換是通過(guò)靜態(tài)的 InternalHandler 完成的

  3. InternalHandler 創(chuàng)建時(shí)自動(dòng)綁定 MainLooper 涡真,所以處理事件運(yùn)行在主線程

  4. 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)行在了子線程

  5. doInBackground 執(zhí)行結(jié)束之后會(huì)使用 InternalHandler 發(fā)消息將當(dāng)前 AsyncTask 和 返回值傳遞到主線程

  6. 主線程處理消息時(shí)調(diào)用對(duì)應(yīng) AsyncTask 的 finish 方法吗铐,處理 onCanclelled 和 onPostExecute 方法

  7. 子線程運(yùn)行過(guò)程中的進(jìn)度提交也是通過(guò)類似方式东亦,在 doInBackground 中調(diào)用 publishProgress 方法,該方法會(huì)將進(jìn)度使用 InternalHandler 提交

  8. 主線程收到 InternalHandler 發(fā)來(lái)的進(jìn)度之后唬渗,通過(guò) onProgressUpdata 接收進(jìn)度并做相應(yīng)處理

  9. 運(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 方法

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末撑蒜,一起剝皮案震驚了整個(gè)濱河市歹啼,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌座菠,老刑警劉巖狸眼,帶你破解...
    沈念sama閱讀 221,820評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異浴滴,居然都是意外死亡拓萌,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)升略,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)微王,“玉大人,你說(shuō)我怎么就攤上這事品嚣÷钤叮” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,324評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵腰根,是天一觀的道長(zhǎng)激才。 經(jīng)常有香客問(wèn)我,道長(zhǎng)额嘿,這世上最難降的妖魔是什么瘸恼? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,714評(píng)論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮册养,結(jié)果婚禮上东帅,老公的妹妹穿的比我還像新娘。我一直安慰自己球拦,他們只是感情好靠闭,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布帐我。 她就那樣靜靜地躺著,像睡著了一般愧膀。 火紅的嫁衣襯著肌膚如雪拦键。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,328評(píng)論 1 310
  • 那天檩淋,我揣著相機(jī)與錄音芬为,去河邊找鬼。 笑死蟀悦,一個(gè)胖子當(dāng)著我的面吹牛媚朦,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播日戈,決...
    沈念sama閱讀 40,897評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼询张,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了浙炼?” 一聲冷哼從身側(cè)響起瑞侮,我...
    開(kāi)封第一講書(shū)人閱讀 39,804評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎鼓拧,沒(méi)想到半個(gè)月后半火,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,345評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡季俩,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評(píng)論 3 340
  • 正文 我和宋清朗相戀三年钮糖,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片酌住。...
    茶點(diǎn)故事閱讀 40,561評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡店归,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出酪我,到底是詐尸還是另有隱情消痛,我是刑警寧澤,帶...
    沈念sama閱讀 36,238評(píng)論 5 350
  • 正文 年R本政府宣布都哭,位于F島的核電站秩伞,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏欺矫。R本人自食惡果不足惜纱新,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望穆趴。 院中可真熱鬧脸爱,春花似錦、人聲如沸未妹。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,417評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至族檬,卻和暖如春歪赢,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背导梆。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,528評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留迂烁,地道東北人看尼。 一個(gè)月前我還...
    沈念sama閱讀 48,983評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像盟步,于是被迫代替她去往敵國(guó)和親藏斩。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容