众所周知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类去实现异步加载。而且子线程不能更给主线程控件属性!