众所周知Android应用开发中不能在UI线程中做耗时的操作,否则就会弹出烦人的ANR窗口。
应用开发中如果需要加载来自网络、磁盘或其他非内存中图片资源时,因加载时间会受到其他因素(如磁盘、网络、图片大小、CPU等等)的影响,很容易产生耗时操作。所以在进行类似操作时要避免在UI线程中进行。今天就和大家分享一下如何通过AsyncTask异步加载图片和怎么处理多线程并发问题
我相信对于初学者来说看不懂太难的代码,所以就简单的实现了下代码如下
package com.blueZhang.HttpUtil.AsyncTask;
import com.blueZhang.HttpUtil.HttpConnectFisGet;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
/**
* 本类是一个通用的图片加载类
* 通过传递过来的String类型的路径参数
* 获取资源的字节数组。然后将字节数组转换成bitmap类型
* 添加进数组返回Bitmap数组
*
* </p>注意:传递过来的要是字符串类型的数组
*
* */
public class ImageAsyncTask extends AsyncTask<String, Void, Bitmap[]> {
private ImageDownLoadListener imageDownLoadListener;
public ImageAsyncTask(ImageDownLoadListener downloadListener) {
this.imageDownLoadListener = downloadListener;
}
protected Bitmap[] doInBackground(String... params) {
Bitmap[] bitmap = new Bitmap[params.length];
if (params[0] != null && params[1] != null) {
try
{
for(int i = 0;i<params.length;i++)
{
byte [] arr = HttpConnectFisGet.getdData(params[i]);//获取网络资源
bitmap[i] = BitmapFactory.decodeByteArray(arr, 0, arr.length);//获取网络资源
}
} catch (Exception e) {
e.printStackTrace();
}
}
return bitmap;
}
@Override
protected void onPostExecute(Bitmap[] result) {
imageDownLoadListener.sendImage(result);
}
/**
* 定义接口以实现接口回调<br/>
* sendImage方法时回调时候实现的方法
* */
public interface ImageDownLoadListener {
public void sendImage(Bitmap... bitMap);
}
}
下面是Text的异步加载类:
package com.blueZhang.HttpUtil.AsyncTask;
import java.io.UnsupportedEncodingException;
import java.util.List;
import com.blueZhang.HttpUtil.HttpConnectFisGet;
import com.blueZhang.HttpUtil.DataAdapter.ViewDataAdapter;
import com.blueZhang.HttpUtil.ParseData.ParseJson;
import android.content.Context;
import android.os.AsyncTask;
import android.widget.ListView;
public class TextAsyncTask<T> extends AsyncTask<String, Void, List<T>> {
private ListView listView ;
private Context context ;
private List<T> list ;
public TextAsyncTask(ListView listView ,Context context) {
this.listView = listView;
this.context = context;
}
@Override
protected List<T> doInBackground(String... params) {
String DataString;
try {
DataString = new String(HttpConnectFisGet.getdData(params[0]),"utf-8");//调用自己写的方法获取网络资源
list = ParseJson.parseJson(DataString);//这里是解析字符串工具类需要自己写
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return list;
}
protected void onPostExecute(List<T> result) {
ViewDataAdapter<T> adapter = new ViewDataAdapter<T>(result,context);
listView.setAdapter(adapter);
};
}
要注意的就是:如果在主线程连接网络获取资源,超过五秒将会被认为是“耗时操作” 那么程序将不会正常运行。所以要使用异步加载类AsyncTask类去实现异步加载。而且子线程不能更给主线程控件属性!