AsyncTask官網API翻譯
官方API翻譯
AsyncTask使開發者可以更輕鬆的使用UI執行緒。這個類使開發者無需操作Thread
或Handler
便可執行後臺操作並將結果返回到UI執行緒。
AsyncTask被設計為一個圍繞Thread
和Handler
的輔助類,並且不構成通用執行緒框架。理論上AsyncTask應該被用於幾秒鐘的短作業,如果執行緒需要執行一段時間,強烈建議使用java.util.concurrent
包下的Excutor
、ThreadPoolExecutor
和FutureTask
。
非同步任務是指執行在後臺執行緒,而結果需要返回到UI執行緒的計算過程。非同步任務由三個泛型:Params
Progress
和Result
,以及四個步驟:呼叫onPreExecute
、doInBackground
、onProgressUpdate
、onPostExecute
組成。
用法
AsyncTask在使用前需要先被繼承並覆蓋doInBackground()
等方法。通常還會覆蓋onPostExecute()
方法。
例如
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
然後只需一行程式碼便可讓其建立並執行:
new DownloadFilesTask().execute(url1, url2, url3);
AsyncTask的泛型型別
非同步任務用到的三種泛型型別如下:
1. Params
任務執行時需要傳遞的引數的型別。
1. Progress
後臺執行期間返回的進度的型別。
1. Result
後臺執行的返回結果的型別。
這三個泛型並非都會被用到,用Void
說明該泛型未被使用:
private class MyTask extends AsyncTask<Void, Void, Void> { ... }
四個步驟
每個非同步任務的執行都需要經過4個步驟:
1. onPreExecute()
後臺任務執行前在UI執行緒上的回撥。一般用於初始化task並在介面上顯示進度條。
1. doInBackground()
在後臺執行緒被呼叫,在onPreExecute()
執行完後立即執行。這一步被用來在後臺執行耗時操作。非同步任務的引數在這裡被傳遞進來。運算處理的結果會在這一步返回給最後一步。可以在此方法中呼叫publishProgress()
將進度返回給UI執行緒的onProgressUpdate()
1. onProgressUpdate()
在呼叫publishProgress()
之後被呼叫,執行在UI執行緒,其執行時間是不確定的。該方法用於後臺任務執行時在使用者介面顯示進度。
1. onPostExecute()
後臺任務結束後被呼叫,執行在UI執行緒。後臺任務的結果會在這裡以引數形式傳遞進來。
取消任務
可以通過呼叫cancle()
取消任務,之後如果呼叫isCancelled()
時會返回true。如果呼叫了cancle()
,在doInBackGround()
之後會執行onCancelled()
而不是onPostExcute()
。為了保證task儘快被取消,應該適時的在odInBackGround()
中呼叫isCancelled()
來獲取當然task狀態。
執行緒規則
一下是使用本類時必須遵守的幾個執行緒規則
- AsyncTask必須在UI執行緒中被載入。
- AsyncTask例項必須在UI執行緒中建立。
- execute()
方法必須在UI執行緒中呼叫。
- 不能手動呼叫的方法:onPreExecute()
、onPostExecute()
、doInBackground()
、onProgressUpdate()
。
- 只能執行一次。(再次執行會拋異常)
可觀察記憶體
AsyncTask保證所有回撥都同步呼叫,因此下面的操作都是執行緒安全的。
- 在構造方法或onPreExecute()
中給成員賦值,然後在doInBackGroudn()
中使用。
- 在doInBackGround()
中賦值,然後在onProgressUpdate()和
onPostExecute()`中使用。
執行順序
期初,多個AsyncTask連續的在同一個後臺執行緒執行。DONUT之後,多個AsyncTask線上程池的不同執行緒中並行執行。HONEYCOMB之後,多個task在同一個執行緒執行避免並行執行引發的應用錯誤。
如果確實需要並行執行,可以用’THREAD_POOL_EXECUTOR’呼叫executeOnExecutor(java.util.concurrent.Executor,Object[])