AsyncTask暫且翻譯為非同步任務
概述:
AsyncTask使UI線程的使用變得恰當和簡單。這個類允許在後台執行操作並且在UI線程呈現處理的結果,無需操作線程。
一個非同步任務是指在後台啟動並執行線程,其運行結果在UI線程呈現。
一個非同步任務由3個泛型和4個步驟定義完成。
用法:
一個AsyncTask必須要被繼承才能使用。這個子類必須重寫doInBackground(Params...)方法,通常還要重寫onPostExecute(Result)方法。
下面是一個子類的列子,來自官方文檔:
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));
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
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));
}
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);
new DownloadFilesTask().execute(url1, url2, url3);
AsyncTask的泛型:
這3種類型使用如下
1.Params,任務執行時輸入的參數類型
2.Progress,背景工作執行的百分比進度
3.Result,背景工作執行後的返回結果,比如String
AsyncTask執行的4個步驟:
一個非同步任務執行時,經曆如下4個步驟:
1. onPreExecute() ,當任務被執行後立即被UI線程調用。這一步通常用來設定這個任務,比如在使用者介面顯示一個進度條。
2.doInBackground(Params...) 在onPreExeecte執行完後立即在後台運行。這一步通常用來執行背景耗時操作。任務的參數會傳遞到這一步來,其運算結果被返回並傳遞給最後一步。在這一步也可以調用publishProgress(Progress...)來更新任務進度。這些值會在onProgressUpdate(Progress...)時被UI線程公布出來。
3.onProgressUpdate(Progress).在publisProgress(Progress...)被調用後由UI線程喚起,其執行時間是不確定的。這個方法用來在使用者介面中顯示後台操作的執行進度。比如,它可以用來動態顯示一個進度條或者在文字框顯示日誌。
4.OnPostExecute(Result) 在後台操作執行完後由UI線程調用。在這一步,後台操作啟動並執行結果會被當做一個參數傳遞給它,即Result。
取消一個任務:
通過調用cancel(boolean),一個任務可以在任意時刻被取消。調用這個方法會導致後面調用isCancelled()返回true。調用這個方法後,在doInBackground(Params...)返回時將不再調用onPostExecute(object)而是調用onCancelled(object).為了儘快取消一個任務,你必須周期性地在doInBackgrouond(object)中檢查isCancelled()的傳回值。如果可能的話,比如可以在一個迴圈內這麼幹。
注意事項:
任務的執行個體必須在UI線程建立
execute(Params...)必須在UI線程調用
不要手動調用onPreExecute(),onPostExecute(Result),doInBackgrouond(Params...),onProgressUpdate(Progress..)
任務只會執行一次,如果嘗試執行第二次則會拋出一個異常。
摘自 厚積而薄發,水到而渠成