AsyncTask面試詳解

weixin_34054866發表於2017-10-23

1、什麼是AsyncTask

它本質上就是封裝了執行緒池和Handler的非同步框架,這個AsyncTask框架主要是來進行執行非同步任務的。因為它內部整合了Handler所以說它可以在內部執行緒和工作執行緒進行靈活的切換。

2、AsyncTask的使用方法

2.1三個引數

Params: 啟動任務執行的輸入引數,比如HTTP請求的URL

Progress: 後臺任務執行的百分比。

Result 後臺執行任務最終返回的結果,比如String,Integer等。

2.2五個方法

onPreExecute(), 該方法將在執行實際的後臺操作前被UI 執行緒呼叫。可以在該方法中做一些準備工作,如在介面上顯示一個進度條,或者一些控制元件的例項化,這個方法可以不用實現

doInBackground(Params...), 將在onPreExecute 方法執行後馬上執行,該方法執行在後臺執行緒中。這裡將主要負責執行那些很耗時的後臺處理工作。可以呼叫 publishProgress方法來更新實時的任務進度。該方法是抽象方法,子類必須實現。

onProgressUpdate(Progress...),在publishProgress方法被呼叫後,UI 執行緒將呼叫這個方法從而在介面上展示任務的進展情況,例如通過一個進度條進行展示。

onPostExecute(Result), 在doInBackground 執行完成後,onPostExecute 方法將被UI 執行緒呼叫,後臺的計算結果將通過該方法傳遞到UI 執行緒,並且在介面上展示給使用者.

onCancelled(),在使用者取消執行緒操作的時候呼叫。在主執行緒中呼叫onCancelled()的時候呼叫。

這裡主要用到了 AsyncTask類的cancle() 方法要想中斷任務 呼叫cancle()方法時要傳遞boolean引數為true ,並且中斷成功之後返回true, 並且執行onCancelled()方法,onPostExceute()方法將不在執行,否則返回false

1852880-95eee11631405ab3.png

3、AsyncTask內部原來

3.1AsyncTask的本質是一個靜態的執行緒池,AsyncTask派生出的子類可以實現不同的非同步任務,這些任務都是提交到靜態的執行緒池中執行

3.2執行緒池中的工作執行緒執行doInBackground(mParams)方法執行非同步任務

3.3當任務狀態改變之後,工作執行緒會向UI執行緒傳送訊息,AsyncTask內部的InternaHandler響應這些訊息,並呼叫相關的回撥函式。

4、AsyncTask的注意事項

4.1記憶體洩露

AsyncTask會被宣告成Activity的非靜態內部類,會持有Activity的匿名的外部的引用。這時候Activity被銷燬了,由於AsyncTask還在執行耗時任務並持有外部的引用,導致Activity無法被回收。

把AsyncTask設定成靜態的(static),同時可以在靜態的AsyncTask內部持有外部的Activity的弱引用。還可以在Activity的onDestory()方法裡,進行AsyncTask的cancel()進行回收

4.2生命週期

AsyncTask的宣告週期,不會隨著Activity的銷燬而銷燬。只有在Activity的onDestory()方法裡進行AsyncTask的cancel()進行回收。AsyncTask才會被銷燬,否者Activity銷燬的時候沒有執行cancle()方法,可能會導致程式奔潰。AsyncTask想要處理的View是依託於Activity,而Activity不存在了。

4.3結果丟失

螢幕旋轉和記憶體不夠程式被系統回收,會導致Activity會被重新建立。而之前建立的AsyncTask會持有之前Activity的引用,但是這個引用已經無效了。所以這個時候再去呼叫AsyncTask的onPostExecute()方法是不會生效的,這就是結果丟失的原因

4.4並行or序列

1.6之前AsyncTask是序列的,1.6-2.3是並行的。在2.3之後為了維護系統的穩定又改成了序列,但是還是可以執行並行的。只需呼叫AsyncTask.executeOnExecutor(exec,"Task 1")方法

publicstaticExecutorService exec = Executors.newFixedThreadPool(10);

一般建議序列,為了執行緒池的穩定。

相關文章