Posted on 2010-07-30 11:59
oathleo 阅读(1338)
评论(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()里再去做相应的结果处理。