Posted on 2010-07-30 11:59
oathleo 閱讀(1341)
評(píng)論(1) 編輯 收藏 所屬分類(lèi):
Android
很明顯UI上的線程安全在Android上控制的也很?chē)?yán)格
如果需要做大運(yùn)算,取網(wǎng)絡(luò)數(shù)據(jù)等,得用AsyncTask
AsyncTask
首先AsyncTask是一個(gè)抽象類(lèi),子類(lèi)繼承AsyncTask必須實(shí)現(xiàn)其抽象方法doInBackground(Params…)。同時(shí)我們還需要實(shí)現(xiàn)onPostExecute(Result),因?yàn)榻Y(jié)果會(huì)在Result中返回。
AsyncTask的生命周期
AsyncTask的生命周期分為四部分,每部分對(duì)應(yīng)一回調(diào)方法,我們只需實(shí)現(xiàn)這些方法中的某些需要用到的方法。程序執(zhí)行過(guò)程中這些會(huì)自動(dòng)調(diào)用它們。
- onPreExecute():任務(wù)執(zhí)行之前執(zhí)行,可在這顯示進(jìn)度條。
- doInBackground(Params…):后臺(tái)執(zhí)行,主要用于完成需要任務(wù)。執(zhí)行過(guò)程中可以調(diào)用publicProgress(Progress…)來(lái)更新任務(wù)的進(jìn)度。
- onProgressUpdate(Progress…):主線程執(zhí)行,用于顯示任務(wù)執(zhí)行的進(jìn)度。
- onPostExecute(Result):主線程執(zhí)行,任務(wù)執(zhí)行的結(jié)果作為此方法的參數(shù)返回。
AsyncTask中的三種泛型
AsyncTask中的三種泛型類(lèi)型為Params、Progress、Result。
- Params:?jiǎn)?dòng)任務(wù)參數(shù),比如請(qǐng)求的資源地址。
- Progress:顧名思義,后臺(tái)任務(wù)執(zhí)行的百分比。
- Result:后臺(tái)執(zhí)行任務(wù)返回的結(jié)果。
AsyncTask的執(zhí)行
AsyncTask只能在在主線程中創(chuàng)建實(shí)例,創(chuàng)建實(shí)例后使用execute(params)執(zhí)行。任務(wù)僅會(huì)執(zhí)行一次,如果想再調(diào)用就必須創(chuàng)建新的實(shí)例。
具體實(shí)現(xiàn)
首先我們先繼承實(shí)現(xiàn)AsyncTask,然后在主線程的getView()里創(chuàng)建其實(shí)例execute().
1、實(shí)現(xiàn)AsyncTask
public class DownImageTask extends AsyncTask {
private ImageView gView;
protected Bitmap doInBackground(ImageView... views) {
Bitmap bmp = null;
ImageView view = views[0];
HotelListData.Item item;
// 根據(jù)iconUrl獲取圖片并渲染,iconUrl的url放在了view的tag中。
if (view.getTag() != null) {
try {
item = (HotelListData.Item) view.getTag();
URL url = new URL(item.getI().toString());
HttpURLConnection conn = (HttpURLConnection) url
.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream stream = conn.getInputStream();
bmp = BitmapFactory.decodeStream(stream);
Data.imageMap.put(item.getId(), bmp);
stream.close();
} catch (Exception e) {
Log.v("img", e.getMessage());
return null;
}
}
this.gView = view;
return bmp;
}
protected void onPostExecute(Bitmap bm) {
if (bm != null) {
this.gView.setImageBitmap(bm);
this.gView = null;
}
}
}
2、在UI主線程中創(chuàng)建其實(shí)例并execute()執(zhí)行
HotelListData dlData = new HotelListData();
HotelListData.Item item = dlData.new Item();
item = (HotelListData.Item) infoVector.getLs().elementAt(position);
holder.text0.setText(item.getN());
holder.star.setImageDrawable(getResources().getDrawable(
imageIndex[Integer.parseInt(item.getS().toString())]));
holder.text2.setText(item.getP());
holder.text3.setText(item.getA());
if (item.getI() != null && (!item.getI().equals(""))) {
Bitmap bm = returnBitMap(item.getId());
if (bm != null) {
holder.image.setImageBitmap(bm);
} else {
if (!holder.image.isDrawingCacheEnabled()
|| !holder.image.getTag().equals(item.getI())) {
holder.image.setImageResource(R.drawable.img_loading);
holder.image.setTag(item);
try {
new DownImageTask().execute(holder.image);
holder.image.setDrawingCacheEnabled(true);
} catch (Exception e) {
Log.e("error",
"RejectedExecutionException in content_img: "
+ item.getI());
}
}
}
}
簡(jiǎn)要
首先創(chuàng)建了DownImageTask,該類(lèi)繼承實(shí)現(xiàn)了AsyncTask的doInBackground()和onPostExecute(),
如上面所介紹,當(dāng)在getView中創(chuàng)建實(shí)例并execute()傳入需要獲取資源地址URL(地址在TAG中)執(zhí)行異步線程任務(wù)后,程序首先調(diào)用
doInBackground()。
doInBackground()從傳入的Image TAG中獲取資源的URL地址進(jìn)行圖片的獲取,獲取完畢Retrun結(jié)果給onPostExecute(),onPostExecute()里再去做相應(yīng)的結(jié)果處理。