单线程轮循机制批量下载图片

来源:互联网 发布:vr反畸变算法 编辑:程序博客网 时间:2024/05/17 02:04

listview 在为item 添加从网上下载下来的图片时, 如果每次都整合一个item时都需要new一个Thread去下载图片,listview长时间滑动时会产生大量线程。

用单线程轮循机制则可以解决这个问题

步骤如下:

1、需要一个任务集合

class imageViewTask{String path;Bitmap bitmap;int position;}
// 任务集合private List<imageViewTask> imageviews = new ArrayList<MusicAdapter.imageViewTask>();

2、在构造方法中创建一个线程,通过任务集合中的path去网上下载图片获得bitmap并放置在这个任务中以Message的obj形式传送给handler处理。

只有在为listview设置适配器时才需要创建这个工作线程, 且只有一个


(while(true)循环 在activity  调用OnDestroy )才会终止

// 获得图片bitmapworkThread = new Thread(){public void run() {while(isLoop){if(!imageviews.isEmpty()){try {Message msg = new Message();// 获得图片的bitmapmsg.obj =  GetImageviewBitmap();msg.what = HANDLER_LOAD_IMAGEVIEW_SUCCESS;// 发消息给主线程handler.sendMessage(msg);} catch (IOException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}}else{synchronized (workThread) {try {//任务队列为空则等待workThread.wait();} catch (InterruptedException e) {e.printStackTrace();}}}}
//GetImageviewBitmap()方法
// 获得图片的bitmapprivate imageViewTask  GetImageviewBitmap() throws Exception, IOException {imageViewTask ivt = imageviews.remove(0);String uri = BasicUri.BasicHttpUri+ivt.path;HttpEntity entity = new HttpUtils().SetHttp(uri, HttpUtils.GET_METHOD, null);byte[] bytes = EntityUtils.toByteArray(entity);Bitmap  bitmap = BitmapUtils.loadBitmap(bytes, 50, 50);// 将网上下载的图片存入缓存集合中map.put(ivt.path, new SoftReference<Bitmap>(bitmap));ivt.bitmap = bitmap;return ivt;}};workThread.start();}




这个是httpUtils工具

public class HttpUtils {public final static int GET_METHOD = 1;public final static int POST_MEHTOD = 2;/** * 构造方法 * @param uri 路径  * @param method 发送消息模式 GET_METHOD用get方式传送消息   POST_MEHTOD用post方式传送消息 */public static HttpEntity SetHttp(String uri, int method, List<NameValuePair> pairs) throws Exception{HttpClient client=new DefaultHttpClient();HttpResponse resp = null;switch (GET_METHOD) {// 用get方式发送消息case GET_METHOD:HttpGet get=new HttpGet(uri);resp=client.execute(get);break;// 用post方式发送消息case POST_MEHTOD:HttpPost post=new HttpPost(uri);HttpEntity entity=new UrlEncodedFormEntity( pairs, "utf-8");post.setEntity(entity);post.setHeader("Content-Type", "application/x-www-form-urlencoded");resp=client.execute(post);break;}return resp.getEntity();}}



3、在自定义adapter 的setView方法中在任务中放置图片下载的path和position, 并为item中的imageview设置标记, 为了在listview的item中放入图片时的方便。

// 给imageview设置标记holder.iv.setTag(position);// 增加任务队列imageViewTask task  = new imageViewTask();task.path = musics.get(position).getAlbumpic();task.position = position;imageviews.add(task);// 通知工作线程可以下载图片了synchronized (workThread) {workThread.notify();}

4、传送消息给主线程,让hanler去更新UI

// handlerprivate Handler handler = new Handler(){public void handleMessage(android.os.Message msg) {switch (msg.what) {case HANDLER_LOAD_IMAGEVIEW_SUCCESS:// 更新UIimageViewTask ivt = (imageViewTask) msg.obj;ImageView iv = (ImageView) listview.findViewWithTag(ivt.position);if(iv != null){if(ivt.bitmap != null)iv.setImageBitmap(ivt.bitmap);}else{iv.setImageResource(R.drawable.ic_launcher);}break;}};};


0 0
原创粉丝点击