Posted on 2010-07-30 11:59
oathleo 閱讀(1340)
評論(1) 編輯 收藏 所屬分類:
Android
很明顯UI上的線程安全在Android上控制的也很嚴格
如果需要做大運算,取網絡數據等,得用AsyncTask
AsyncTask
首先AsyncTask是一個抽象類,子類繼承AsyncTask必須實現其抽象方法doInBackground(Params…)。同時我們還需要實現onPostExecute(Result),因為結果會在Result中返回。
AsyncTask的生命周期
AsyncTask的生命周期分為四部分,每部分對應一回調方法,我們只需實現這些方法中的某些需要用到的方法。程序執行過程中這些會自動調用它們。
- onPreExecute():任務執行之前執行,可在這顯示進度條。
- doInBackground(Params…):后臺執行,主要用于完成需要任務。執行過程中可以調用publicProgress(Progress…)來更新任務的進度。
- onProgressUpdate(Progress…):主線程執行,用于顯示任務執行的進度。
- onPostExecute(Result):主線程執行,任務執行的結果作為此方法的參數返回。
AsyncTask中的三種泛型
AsyncTask中的三種泛型類型為Params、Progress、Result。
- Params:啟動任務參數,比如請求的資源地址。
- Progress:顧名思義,后臺任務執行的百分比。
- Result:后臺執行任務返回的結果。
AsyncTask的執行
AsyncTask只能在在主線程中創建實例,創建實例后使用execute(params)執行。任務僅會執行一次,如果想再調用就必須創建新的實例。
具體實現
首先我們先繼承實現AsyncTask,然后在主線程的getView()里創建其實例execute().
1、實現AsyncTask
public class DownImageTask extends AsyncTask {
private ImageView gView;
protected Bitmap doInBackground(ImageView... views) {
Bitmap bmp = null;
ImageView view = views[0];
HotelListData.Item item;
// 根據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主線程中創建其實例并execute()執行
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());
}
}
}
}
簡要
首先創建了DownImageTask,該類繼承實現了AsyncTask的doInBackground()和onPostExecute(),
如上面所介紹,當在getView中創建實例并execute()傳入需要獲取資源地址URL(地址在TAG中)執行異步線程任務后,程序首先調用
doInBackground()。
doInBackground()從傳入的Image TAG中獲取資源的URL地址進行圖片的獲取,獲取完畢Retrun結果給onPostExecute(),onPostExecute()里再去做相應的結果處理。