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()里再去做相应的结果处理。



你可能感兴趣的:(Android线程安全)