android: 使用 AsyncTask
9.2.4??? 使用 AsyncTask
?
不過為了更加方便我們在子線程中對 UI 進行操作,Android 還提供了另外一些好用的工 具,AsyncTask 就是其中之一。借助 AsyncTask,即使你對異步消息處理機制完全不了解, 也可以十分簡單地從子線程切換到主線程。當然,AsyncTask 背后的實現(xiàn)原理也是基于異步 消息處理機制的,只是 Android 幫我們做了很好的封裝而已。
首先來看一下 AsyncTask 的基本用法,由于 AsyncTask 是一個抽象類,所以如果我們想 使用它,就必須要創(chuàng)建一個子類去繼承它。在繼承時我們可以為 AsyncTask 類指定三個泛型 參數(shù),這三個參數(shù)的用途如下。
1.??? Params
在執(zhí)行?AsyncTask 時需要傳入的參數(shù),可用于在后臺任務(wù)中使用。
2.??? Progress
后臺任務(wù)執(zhí)行時,如果需要在界面上顯示當前的進度,則使用這里指定的泛型作為 進度單位。
3.??? Result
當任務(wù)執(zhí)行完畢后,如果需要對結(jié)果進行返回,則使用這里指定的泛型作為返回值 類型。
因此,一個最簡單的自定義 AsyncTask 就可以寫成如下方式:
?
class DownloadTask extends AsyncTask<Void, Integer, Boolean> {
……
}
這里我們把 AsyncTask 的第一個泛型參數(shù)指定為 Void,表示在執(zhí)行 AsyncTask 的時候不 需要傳入?yún)?shù)給后臺任務(wù)。第二個泛型參數(shù)指定為 Integer,表示使用整型數(shù)據(jù)來作為進度顯 示單位。第三個泛型參數(shù)指定為 Boolean,則表示使用布爾型數(shù)據(jù)來反饋執(zhí)行結(jié)果。
當然,目前我們自定義的 DownloadTask 還是一個空任務(wù),并不能進行任何實際的操作, 我們還需要去重寫 AsyncTask 中的幾個方法才能完成對任務(wù)的定制。經(jīng)常需要去重寫的方法 有以下四個。
1.??? onPreExecute()
這個方法會在后臺任務(wù)開始執(zhí)行之前調(diào)用,用于進行一些界面上的初始化操作,比 如顯示一個進度條對話框等。
2.??? doInBackground(Params...)
這個方法中的所有代碼都會在子線程中運行,我們應(yīng)該在這里去處理所有的耗時任 務(wù)。任務(wù)一旦完成就可以通過 return 語句來將任務(wù)的執(zhí)行結(jié)果返回,如果 AsyncTask 的 第三個泛型參數(shù)指定的是 Void,就可以不返回任務(wù)執(zhí)行結(jié)果。注意,在這個方法中是不 可以進行 UI 操作的,如果需要更新 UI 元素,比如說反饋當前任務(wù)的執(zhí)行進度,可以調(diào) 用 publishProgress(Progress...)方法來完成。
3.??? onProgressUpdate(Progress...)
當在后臺任務(wù)中調(diào)用了 publishProgress(Progress...)方法后,這個方法就會很快被調(diào) 用,方法中攜帶的參數(shù)就是在后臺任務(wù)中傳遞過來的。在這個方法中可以對 UI 進行操 作,利用參數(shù)中的數(shù)值就可以對界面元素進行相應(yīng)地更新。
4.??? onPostExecute(Result)
當后臺任務(wù)執(zhí)行完畢并通過 return 語句進行返回時,這個方法就很快會被調(diào)用。返 回的數(shù)據(jù)會作為參數(shù)傳遞到此方法中,可以利用返回的數(shù)據(jù)來進行一些 UI 操作,比如 說提醒任務(wù)執(zhí)行的結(jié)果,以及關(guān)閉掉進度條對話框等。
因此,一個比較完整的自定義 AsyncTask 就可以寫成如下方式:
?
class DownloadTask extends AsyncTask<Void, Integer, Boolean> {
?
?@Override
protected void onPreExecute() {
progressDialog.show(); // 顯示進度對話框
}
?
@Override
protected Boolean doInBackground(Void... params) {
try {
while (true) {
int downloadPercent = doDownload(); // 這是一個虛構(gòu)的方法
publishProgress(downloadPercent);
if (downloadPercent >= 100) {
break;
}
}
} catch (Exception e) {
return false;
}
return true;
}
?
@Override
protected void onProgressUpdate(Integer... values) {
// 在這里更新下載進度
progressDialog.setMessage("Downloaded " + values[0] + "%");
}
?
?
@Override
protected void onPostExecute(Boolean result) {
progressDialog.dismiss(); // 關(guān)閉進度對話框
// 在這里提示下載結(jié)果
if (result) {
Toast.makeText(context, "Download succeeded", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, " Download failed", Toast.LENGTH_SHORT).show();
}
}
}
?
在這個 DownloadTask 中,我們在 doInBackground()方法里去執(zhí)行具體的下載任務(wù)。這個方法里的代碼都是在子線程中運行的,因而不會影響到主線程的運行。注意這里虛構(gòu)了一個 doDownload()方法,這個方法用于計算當前的下載進度并返回,我們假設(shè)這個方法已經(jīng)存在 了 。 在 得 到 了 當 前 的 下 載 進 度 后 , 下 面 就 該 考 慮 如 何 把 它 顯 示 到 界 面 上 了 , 由 于 doInBackground()方法是在子線程中運行的,在這里肯定不能進行 UI 操作,所以我們可以調(diào) 用 publishProgress()方法并將當前的下載進度傳進來,這樣 onProgressUpdate()方法就會很快 被調(diào)用,在這里就可以進行 UI 操作了。
當下載完成后,doInBackground()方法會返回一個布爾型變量,這樣 onPostExecute()方 法就會很快被調(diào)用,這個方法也是在主線程中運行的。然后在這里我們會根據(jù)下載的結(jié)果來 彈出相應(yīng)的 Toast 提示,從而完成整個 DownloadTask 任務(wù)。
簡單來說,使用 AsyncTask 的訣竅就是,在 doInBackground()方法中去執(zhí)行具體的耗時 任務(wù),在 onProgressUpdate()方法中進行 UI 操作,在 onPostExecute()方法中執(zhí)行一些任務(wù)的 收尾工作。
如果想要啟動這個任務(wù),只需編寫以下代碼即可:
new DownloadTask().execute();
以上就是 AsyncTask 的基本用法,怎么樣,是不是感覺簡單方便了許多?我們并不需要 去考慮什么異步消息處理機制,也不需要專門使用一個 Handler 來發(fā)送和接收消息,只需要 調(diào)用一下 publishProgress()方法就可以輕松地從子線程切換到 UI 線程了。
總結(jié)
以上是生活随笔為你收集整理的android: 使用 AsyncTask的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 探索PHP7(一)--性能
- 下一篇: linux下安装jira详细步骤