AsyncTask原理

AsyncTask只要是學習Android的如果你不會用這個,或者對它里面的哪個方法不熟悉那么你要仔細了解一下了,因為這個可能在開發(fā)中很長用,并且也很有用。

AsyncTask類必須在主線程中加載,在Android4.1以及以上版本中已經(jīng)被系統(tǒng)自動加載完成。

其它不說了,直接上干貨。

AsyncTask的常用方法:

1、onPreExecute(), 在主線程中執(zhí)行,在異步任務開始之前執(zhí)行(即一旦執(zhí)行)

2、doInBackground(Params...params)

3、onProgressUpdate(Progress...values)

4、onPostExecute(Result result)


AsyncTask的使用限制:

1、AsyncTask必須在主線程中創(chuàng)建

2、execute()方法必須在UI線程中調(diào)用

3、不要直接在程序中調(diào)用它的上面4個常用方法

4、一個AsyncTask對象只能執(zhí)行一次,否則報異常

為什么對象只能執(zhí)行一次呢?看源碼如下圖1:


圖1

看紅色部分,一旦你執(zhí)行了AsyncTask對象的execute()方法,那么會先判斷mStatus的狀態(tài),而mStatus的默認狀態(tài)是

圖2

執(zhí)行了execute()方法后,mStatus就變?yōu)镾tatus.RUNNING,如果你多次調(diào)用execute()那么就會走execute的switch語句,拋出IllegalStateException異常。

onPreExecute()在主線程執(zhí)行,看圖1就會發(fā)現(xiàn)為什么了。

走到現(xiàn)在,又發(fā)現(xiàn)幾個不知道什么鬼的東西,分別是mWorker,mWorker.mParams ,sExecutor, mFuture,這些都是什么鬼啊???

別急咱們一個一個跟它,首先來看mWorker,看它的定義如圖3。


圖3

使用SourceInsight點擊mWorker出現(xiàn)圖3,知道m(xù)Worker是一個WorkerRunnable對象,顧名思義,WorkerRunnable應該是一個實現(xiàn)了Runnable接口的類,是不是,咱們看它的源碼,看下圖4-WorkerRunnable


圖4-WorkerRunnable

我去,mWorker竟然是實現(xiàn)的 java.util.concurrent.Callable,它本身是AsyncTask的一個私有、靜態(tài)、抽象類,打臉了啊^_^ !!!

沒關系,打就打吧,不過 mWorker.mParams搞明白了吧 ,接著看Callable源碼如圖5-Callable:


圖5-Callable

Callable是Java同步包下的內(nèi)容一般和線程池,F(xiàn)uture聯(lián)合起來使用,用于非阻塞線程這里不做詳細論述此處我們只討論AsyncTask(OkHttp也是使用Future與Callable+線程池實現(xiàn)的),如果你對Callable不了解 http://blog.csdn.net/ghsau/article/details/7451464?看這篇博客學習一下最好。

現(xiàn)在還剩下sExecutor和mFuture了,他們的定義吧,如下圖6:


圖6

FutureTask 實現(xiàn)RunnableFuture ,RunnableFuture如下圖7


圖7

FutureTask 具體內(nèi)容可以參考?http://blog.csdn.net/javazejian/article/details/50896505?我不覺得我比別人講的更好,所以不廢話了。

OK,目前為止execute(Params...params)方法中的所有東西我們已經(jīng)知道都是什么了,現(xiàn)在看看它們的初始化吧,如下圖9


圖9

結(jié)合圖1+圖9,這兩段代碼來看,線程池執(zhí)行是會執(zhí)行mFuture的run()方法,源碼如下 圖10:


圖10

run()方法我就不在追蹤了啊, 圖1的mExceture.excute(mFuture)執(zhí)行圖10的run()方法,進入后在調(diào)用Callable的call()方法返回結(jié)果,無異常時,調(diào)用set(result),在set方法中調(diào)用finishCompletion()->在此方法中調(diào)用done()方法完整整個流程,而AsyncTask在進行初始化時,就重寫了done()方法,將結(jié)果分裝到handler的Message中,如圖11


圖11

下面看sHandler和AsyncTaskResult源碼:

圖12是AsyncTaskResult的源碼,它存儲AsyncTask對象以及FutureTask執(zhí)行結(jié)果

圖12

在來看

message = sHandler.obtainMessage(MESSAGE_POST_RESULT, ? new AsyncTaskResult(AsyncTask.this, result));

message.sendToTarget();

sHandler的源碼如下:

圖13

執(zhí)行msg.what == MESSAGE_POST_RESULT時,執(zhí)行AsyncTask的私有的finish()方法如圖14


圖14

在執(zhí)行finish()時,執(zhí)行onPostExecute()一個完整的AsyncTask過程走完。

sHandler.obtainMessage 默認將Handler的實例對象傳入了啊,具體看源碼


最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容