Android中AsyncTask的用法實(shí)例分享
* AsyncTask
看上去修改后的connect()方法已經(jīng)可用了,但是這種匿名線程的方式是存在缺陷的:第一,線程的開銷較大,如果每個(gè)任務(wù)都要?jiǎng)?chuàng)建一個(gè)線程,那么應(yīng)用 程序的效率要低很多;第二,線程無(wú)法管理,匿名線程創(chuàng)建并啟動(dòng)后就不受程序的控制了,如果有很多個(gè)請(qǐng)求發(fā)送,那么就會(huì)啟動(dòng)非常多的線程,系統(tǒng)將不堪重負(fù)。 另外,前面已經(jīng)看到,在新線程中更新UI還必須要引入handler,這讓代碼看上去非常臃腫。
為了解決這一問題,OPhone在1.5版本引入了AsyncTask。AsyncTask的特點(diǎn)是任務(wù)在主線程之外運(yùn)行,而回調(diào)方法是在主線程中執(zhí)行, 這就有效地避免了使用Handler帶來(lái)的麻煩。閱讀AsyncTask的源碼可知,AsyncTask是使用java.util.concurrent 框架來(lái)管理線程以及任務(wù)的執(zhí)行的,concurrent框架是一個(gè)非常成熟,高效的框架,經(jīng)過了嚴(yán)格的測(cè)試。這說(shuō)明AsyncTask的設(shè)計(jì)很好的解決了 匿名線程存在的問題。
AsyncTask是抽象類,子類必須實(shí)現(xiàn)抽象方法doInBackground(Params... p) ,在此方法中實(shí)現(xiàn)任務(wù)的執(zhí)行工作,比如連接網(wǎng)絡(luò)獲取數(shù)據(jù)等。通常還應(yīng)該實(shí)現(xiàn)onPostExecute(Result r)方法,因?yàn)閼?yīng)用程序關(guān)心的結(jié)果在此方法中返回。需要注意的是AsyncTask一定要在主線程中創(chuàng)建實(shí)例。AsyncTask定義了三種泛型類型 Params,Progress和Result。
* Params 啟動(dòng)任務(wù)執(zhí)行的輸入?yún)?shù),比如HTTP請(qǐng)求的URL。
* Progress 后臺(tái)任務(wù)執(zhí)行的百分比。
* Result 后臺(tái)執(zhí)行任務(wù)最終返回的結(jié)果,比如String。
AsyncTask 的執(zhí)行分為四個(gè)步驟,與前面定義的TaskListener類似。每一步都對(duì)應(yīng)一個(gè)回調(diào)方法,需要注意的是這些方法不應(yīng)該由應(yīng)用程序調(diào)用,開發(fā)者需要做的就是實(shí)現(xiàn)這些方法。在任務(wù)的執(zhí)行過程中,這些方法被自動(dòng)調(diào)用。
* onPreExecute() 當(dāng)任務(wù)執(zhí)行之前開始調(diào)用此方法,可以在這里顯示進(jìn)度對(duì)話框。
* doInBackground(Params...) 此方法在后臺(tái)線程執(zhí)行,完成任務(wù)的主要工作,通常需要較長(zhǎng)的時(shí)間。在執(zhí)行過程中可以調(diào)用publicProgress(Progress...)來(lái)更新任務(wù)的進(jìn)度。
* onProgressUpdate(Progress...) 此方法在主線程執(zhí)行,用于顯示任務(wù)執(zhí)行的進(jìn)度。
* onPostExecute(Result) 此方法在主線程執(zhí)行,任務(wù)執(zhí)行的結(jié)果作為此方法的參數(shù)返回。
PageTask擴(kuò)展了AsyncTask,在 doInBackground()方法中讀取網(wǎng)頁(yè)內(nèi)容。PageTask的源代碼如下所示:
// 設(shè)置三種類型參數(shù)分別為String,Integer,String
class PageTask extends AsyncTask<String, Integer, String> {
// 可變長(zhǎng)的輸入?yún)?shù),與AsyncTask.exucute()對(duì)應(yīng)
@Override
protected String doInBackground(String... params) {
try {
HttpClient client = new DefaultHttpClient();
// params[0] 代表連接的url
HttpGet get = new HttpGet(params[0]);
HttpResponse response = client.execute(get);
HttpEntity entity = response.getEntity();
long length = entity.getContentLength();
InputStream is = entity.getContent();
String s = null;
if (is != null) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[128];
int ch = -1;
int count = 0;
while ((ch = is.read(buf)) != -1) {
baos.write(buf, 0, ch);
count += ch;
if (length > 0) {
// 如果知道響應(yīng)的長(zhǎng)度,調(diào)用publishProgress()更新進(jìn)度
publishProgress((int) ((count / (float) length) * 100));
}
// 為了在模擬器中清楚地看到進(jìn)度,讓線程休眠100ms
Thread.sleep(100);
}
s = new String(baos.toByteArray()); }
// 返回結(jié)果
return s;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onCancelled() {
super.onCancelled();
}
@Override
protected void onPostExecute(String result) {
// 返回HTML頁(yè)面的內(nèi)容
message.setText(result);
}
@Override
protected void onPreExecute() {
// 任務(wù)啟動(dòng),可以在這里顯示一個(gè)對(duì)話框,這里簡(jiǎn)單處理
message.setText(R.string.task_started);
}
@Override
protected void onProgressUpdate(Integer... values) {
// 更新進(jìn)度
message.setText(values[0]);
}
}
執(zhí)行PageTask非常簡(jiǎn)單,只需要調(diào)用如下代碼。重新運(yùn)行NetworkActivity,不但可以抓取網(wǎng)頁(yè)的內(nèi)容,還可以實(shí)時(shí)更新讀取的進(jìn)度。讀者嘗試讀取一個(gè)較大的網(wǎng)頁(yè),看看百分比的更新情況。
PageTask task = new PageTask();
task.execute(url.getText().toString());
下載實(shí)例: testAsync(jb51.net).rar
- Android開發(fā)筆記之:深入理解多線程AsyncTask
- Android的異步任務(wù)AsyncTask詳解
- 詳解Android App中的AsyncTask異步任務(wù)執(zhí)行方式
- Android AsyncTask完全解析 帶你從源碼的角度徹底理解
- 詳解Android中AsyncTask機(jī)制
- Android中通過AsyncTask類來(lái)制作炫酷進(jìn)度條的實(shí)例教程
- Android中使用AsyncTask實(shí)現(xiàn)文件下載以及進(jìn)度更新提示
- Android AsyncTask實(shí)現(xiàn)異步處理任務(wù)的方法詳解
相關(guān)文章
android 網(wǎng)絡(luò)請(qǐng)求庫(kù)volley方法詳解
這篇文章主要介紹了android 網(wǎng)絡(luò)請(qǐng)求庫(kù)volley方法詳解的相關(guān)資料,需要的朋友可以參考下2016-09-09Android Mms之:對(duì)話與聯(lián)系人關(guān)聯(lián)的總結(jié)詳解
本篇文章是對(duì)Android中對(duì)話與聯(lián)系人的關(guān)聯(lián)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05Android自定義listview布局實(shí)現(xiàn)上拉加載下拉刷新功能
這篇文章主要介紹了Android自定義listview布局實(shí)現(xiàn)上拉加載下拉刷新功能,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-12-12RecyclerView+CardView實(shí)現(xiàn)橫向卡片式滑動(dòng)效果
這篇文章主要為大家詳細(xì)介紹了RecyclerView+CardView實(shí)現(xiàn)橫向卡片式滑動(dòng)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01Android RecyclerView實(shí)現(xiàn)滑動(dòng)刪除
這篇文章主要為大家詳細(xì)介紹了Android RecyclerView實(shí)現(xiàn)滑動(dòng)刪除,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-07-07Android 啟動(dòng)第三方程序的方法總結(jié)
這篇文章主要介紹了Android 啟動(dòng)第三方程序的方法總結(jié)的相關(guān)資料,需要的朋友可以參考下2017-04-04