為了解決這一問題,OPhone在1.5版本引入了AsyncTask。AsyncTask的特點是任務(wù)在主線程之外運(yùn)行,而回調(diào)方法是在主線程中執(zhí)行,這就有效地避免了使用Handler帶來 的麻煩。閱讀AsyncTask的源碼可知,AsyncTask是使用java.util.concurrent框架來管理線程以及任務(wù)的執(zhí)行的,concurrent框架是一個非常成熟,高效的框架,經(jīng)過了嚴(yán)格的測試。這說明AsyncTask的設(shè)計很好的解決了匿名線程存在的問題。
AsyncTask是抽象類,子類必須實現(xiàn)抽象方法doInBackground(Params... p),在此方法中實現(xiàn)任務(wù)的執(zhí)行工作,比如連接網(wǎng)絡(luò)獲取數(shù)據(jù)等。通常還應(yīng)該實現(xiàn)onPostExecute(Resultr)方法,因為應(yīng)用程序關(guān)心的結(jié)果在此方法中返回。需要注意的是AsyncTask一定要在主線程中創(chuàng)建實例。AsyncTask定義了三種泛型類型Params,Progress和Result。
* Params啟動任務(wù)執(zhí)行的輸入?yún)?shù),比如HTTP請求的URL。
* Progress后臺任務(wù)執(zhí)行的百分比。
* Result后臺執(zhí)行任務(wù)最終返回的結(jié)果,比如String。
AsyncTask的執(zhí)行分為四個步驟,與前面定義的TaskListener類似。每一步都對應(yīng)一個回調(diào)方法,需要注意的是這些方法不應(yīng)該由應(yīng)用程序調(diào)用,開發(fā)者需要做的就是實現(xiàn)這些方法。在任務(wù)的執(zhí)行過程中,這些方法被自動調(diào)用。
* onPreExecute()當(dāng)任務(wù)執(zhí)行之前開始調(diào)用此方法,可以在這里顯示進(jìn)度對話框。
* doInBackground(Params...)此方法在后臺線程執(zhí)行,完成任務(wù)的主要工作,通常需要較長的時間。在執(zhí)行過程中可以調(diào)用publicProgress(Progress...)來更新任務(wù)的進(jìn)度。
*onProgressUpdate(Progress...)此方法在主線程執(zhí)行,用于顯示任務(wù)執(zhí)行的進(jìn)度。
* onPostExecute(Result)此方法在主線程執(zhí)行,任務(wù)執(zhí)行的結(jié)果作為此方法的參數(shù)返回。
三個泛型參數(shù):
Param 任務(wù)執(zhí)行器需要的數(shù)據(jù)類型
Progress 后臺計算中使用的進(jìn)度單位數(shù)據(jù)類型
Result 后臺計算返回結(jié)果的數(shù)據(jù)類型
有些參數(shù)是可以設(shè)置為不使用的,只要傳遞為Void型即可,比如AsyncTask</VOID,>
四個步驟:
onPreExecute(),執(zhí)行預(yù)處理,它運(yùn)行于UI線程,可以為后臺任務(wù)做一些準(zhǔn)備工作,比如繪制一個進(jìn)度條控件。
doInBackground(Params…),后臺進(jìn)程執(zhí)行的具體計算在這里實現(xiàn),doInBackground(Params…)是AsyncTask的關(guān)鍵,此方法必須重載。在這個方法內(nèi)可以使用publishProgress(Progress…)改變當(dāng)前的進(jìn)度值。
onProgressUpdate(Progress…),運(yùn)行于UI線程。如果在doInBackground(Params…)中使用了publishProgress(Progress…),就會觸發(fā)這個方法。在這里可以對進(jìn)度條控件根據(jù)進(jìn)度值做出具體的響應(yīng)。
onPostExecute(Result),運(yùn)行于UI線程,可以對后臺任務(wù)的結(jié)果做出處理,結(jié)果就是doInBackground(Params…)的返回值。此方法也要經(jīng)常重載,如果Result為null表明后臺任務(wù)沒有完成(被取消或者出現(xiàn)異常)。
這4個方法都不能手動調(diào)用。而且除了doInBackground(Params…)方法,其余3個方法都是被UI線程所調(diào)用的,所以要求:
1) AsyncTask的實例必須在UI thread中創(chuàng)建;
2) AsyncTask.execute方法必須在UI thread中調(diào)用;
Task只能被執(zhí)行一次,多次調(diào)用時將會出現(xiàn)異常,而且是不能手動停止。
packagecn.asyn.rxm;
importandroid.app.Activity;
importandroid.os.AsyncTask;
importandroid.os.Bundle;
importandroid.util.Log;
importandroid.widget.TextView;
public classAsynctaskActivity extends Activity {
TextView tv;
final String TAG="AsyncTaskTest";
@Override
protected void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tv =(TextView) findViewById(R.id.label);
newMyTask().execute(6, 12, 7);
}
class MyTask extendsAsyncTask<Integer, Integer, Integer>{
@Override
protectedvoid onPreExecute() {
super.onPreExecute();
Log.d(TAG,"onPreExecute()");
}
@Override
protectedInteger doInBackground(Integer... params) {
Log.d(TAG,"doInBackground()");
int p = 0;
for (int index = 0; index< params.length; index++) {
int num = params[index];
for (int j = 0; j < num; j++){
if (num -j <= 0) {
break;
}
p++;
publishProgress(p);
try{
Thread.sleep(500);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
return p;
}
@Override
protectedvoid onProgressUpdate(Integer... progress) {
Log.d(TAG,"onProgressUpdate()");
tv.append("nProgress: " +progress[0]);
}
@Override
protectedvoid onPostExecute(Integer result) {
Log.d(TAG,"onPostExecute()");
tv.append("nFinished.Result: " + result);
}
@Override
protectedvoid onCancelled() {
super.onCancelled();
Log.d(TAG,"onCancelled()");
}
}
}
愛華網(wǎng)


