Android小知識-一分鐘看完AsyncTask
使用方式
public final AsyncTask<Params, Progress, Result> execute(Params... params)
Params表示傳入的引數,Progress表示當前的進度,Result表示當任務執行完畢後需要返回的結果。
在使用AsyncTask時,需要重寫它的幾個方法,其中doInBackground(Params… params)方法必須實現,該方法用於執行非同步任務,引數params表示非同步任務的輸入引數,在這個方法中可以通過publishProgress方法來更新任務進度,publishProgress方法會呼叫onProgressUpdate方法,改方法在主執行緒中執行;如果需要在執行非同步之前做一些初始化操作,比如顯示一個進度條,可以重寫它的onPreExecute方法,這個方法執行在主執行緒;當doInBackground方法執行完畢,如果需要非同步任務資料返回給主執行緒,可以重寫onPostExecute(Result result)方法,這個方法在主執行緒中執行,引數result是後臺返回的值,也就是doInBackground方法返回的值。
原理
AsyncTask是一個封裝了執行緒池和Handler的非同步框架,本質上來說就是一個靜態的執行緒池,AsyncTask派生出的子類可以實現不同的非同步任務,這些任務都是提交到靜態的執行緒池中執行。
執行緒池中的工作執行緒執行doInBackground(mParams)方法執行非同步任務。
@WorkerThread protected abstract Result doInBackground(Params... params);
當任務狀態改變之後,工作執行緒會向UI執行緒傳送訊息,AsyncTask內部的InternalHandler響應這些訊息,並呼叫相關回調函式。
@WorkerThread protected final void publishProgress(Progress... values) { if (!isCancelled()) { //獲取InternalHandler併發送訊息重新整理資料 getHandler().obtainMessage(MESSAGE_POST_PROGRESS, new AsyncTaskResult<Progress>(this, values)).sendToTarget(); } } private static class InternalHandler extends Handler { public InternalHandler(Looper looper) { super(looper); } @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"}) @Override public void handleMessage(Message msg) { AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj; switch (msg.what) { case MESSAGE_POST_RESULT: // There is only one result result.mTask.finish(result.mData[0]); break; case MESSAGE_POST_PROGRESS: //通知UI執行緒更新資料 result.mTask.onProgressUpdate(result.mData); break; } } }
注意事項
記憶體洩漏
非靜態內部類AsyncTask會持有外部類Activity的引用,當Activity被回收時,如果AsyncTask內部在做一些耗時操作,這時由於AsyncTask持有了這個activity的引用,導致無法被釋放,導致記憶體洩漏。
建立一個靜態內部類AsyncTask+弱引用WeakReference,在activity的onDestroy中呼叫AsyncTask的cancel方法。
生命週期
AsyncTask並不會隨著Activity銷燬而銷燬。在activity的onDestroy中呼叫AsyncTask的cancel方法。
結果丟失
在螢幕旋轉,或後臺activity由於記憶體不足,AsyncTask持有的當前activity引用是無效的,這時呼叫AsyncTask的onPostExecute方法去更新介面是不會生效的。
並行或序列
AsyncTask在Android 1.6之前是序列任務,在Android 1.6時AsyncTask採用執行緒池處理並行任務,又在Android 3.0開始採用一個執行緒序列執行任務。

掃碼_搜尋聯合傳播樣式-標準色版.png
Android、Java、Python、Go、PHP、IOS、C++、HTML等等技術文章,更有各種書籍推薦和程式員資訊,快來加入我們吧!關注技術共享筆記。

838794-506ddad529df4cd4.webp.jpg
搜尋微信“顧林海”公眾號,定期推送優質文章。