单线程轮循的机制异步批量加载图片

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

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

步骤如下:

1、需要一个任务集合

[java]  view plain  copy
  1. class imageViewTask{  
  2.         String path;  
  3.         Bitmap bitmap;  
  4.         int position;  
  5.     }  
[java]  view plain  copy
  1. // 任务集合  
  2.     private List<imageViewTask> imageviews = new ArrayList<MusicAdapter.imageViewTask>();  

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

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

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

[java]  view plain  copy
  1. // 获得图片bitmap  
  2.         workThread = new Thread(){  
  3.             public void run() {  
  4.                 while(isLoop){  
  5.                     if(!imageviews.isEmpty()){  
  6.                         try {  
  7.                             Message msg = new Message();  
  8.             // 获得图片的bitmap  
  9.                             msg.obj =  GetImageviewBitmap();  
  10.                             msg.what = HANDLER_LOAD_IMAGEVIEW_SUCCESS;  
  11.             // 发消息给主线程  
  12.                             handler.sendMessage(msg);  
  13.                               
  14.                         } catch (IOException e) {  
  15.                             e.printStackTrace();  
  16.                         } catch (Exception e) {  
  17.                             e.printStackTrace();  
  18.                         }  
  19.                           
  20.                     }else{  
  21.                         synchronized (workThread) {  
  22.                             try {  
  23.                                 //任务队列为空则等待  
  24.                                 workThread.wait();  
  25.                             } catch (InterruptedException e) {  
  26.                                 e.printStackTrace();  
  27.                             }  
  28.                         }  
  29.                     }  
  30.                       
  31.                 }  
[java]  view plain  copy
  1. //GetImageviewBitmap()方法  
[java]  view plain  copy
  1. // 获得图片的bitmap  
  2.             private imageViewTask  GetImageviewBitmap() throws Exception, IOException {  
  3.                 imageViewTask ivt = imageviews.remove(0);  
  4.                 String uri = BasicUri.BasicHttpUri+ivt.path;      
  5.                 HttpEntity entity = new HttpUtils().SetHttp(uri, HttpUtils.GET_METHOD, null);  
  6.                 byte[] bytes = EntityUtils.toByteArray(entity);  
  7.                 Bitmap  bitmap = BitmapUtils.loadBitmap(bytes, 5050);  
  8.                 // 将网上下载的图片存入缓存集合中  
  9.                 map.put(ivt.path, new SoftReference<Bitmap>(bitmap));  
  10.                   
  11.                 ivt.bitmap = bitmap;  
  12.                 return ivt;  
  13.             }  
  14.         };  
  15.         workThread.start();  
  16.     }  


这个是httpUtils工具

[java]  view plain  copy
  1. public class HttpUtils {  
  2.       
  3.     public final static int GET_METHOD = 1;  
  4.     public final static int POST_MEHTOD = 2;  
  5.       
  6.     /** 
  7.      * 构造方法 
  8.      * @param uri 路径  
  9.      * @param method 发送消息模式 GET_METHOD用get方式传送消息   POST_MEHTOD用post方式传送消息 
  10.      */  
  11.     public static HttpEntity SetHttp(String uri, int method, List<NameValuePair> pairs) throws Exception{  
  12.         HttpClient client=new DefaultHttpClient();  
  13.         HttpResponse resp = null;  
  14.         switch (GET_METHOD) {  
  15.         // 用get方式发送消息  
  16.         case GET_METHOD:  
  17.             HttpGet get=new HttpGet(uri);  
  18.             resp=client.execute(get);  
  19.             break;  
  20.         // 用post方式发送消息  
  21.         case POST_MEHTOD:  
  22.             HttpPost post=new HttpPost(uri);  
  23.             HttpEntity entity=new UrlEncodedFormEntity( pairs, "utf-8");  
  24.             post.setEntity(entity);  
  25.             post.setHeader("Content-Type",   
  26.                     "application/x-www-form-urlencoded");  
  27.             resp=client.execute(post);  
  28.             break;  
  29.         }  
  30.         return resp.getEntity();  
  31.     }  
  32.     }  



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

[java]  view plain  copy
  1. // 给imageview设置标记  
  2.         holder.iv.setTag(position);  
  3. // 增加任务队列  
  4.         imageViewTask task  = new imageViewTask();  
  5.         task.path = musics.get(position).getAlbumpic();  
  6.         task.position = position;  
  7.         imageviews.add(task);  
  8.         // 通知工作线程可以下载图片了  
  9.         synchronized (workThread) {  
  10.             workThread.notify();  
  11.         }  

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


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

[java]  view plain  copy
  1. // 给imageview设置标记  
  2.         holder.iv.setTag(position);  
  3. // 增加任务队列  
  4.         imageViewTask task  = new imageViewTask();  
  5.         task.path = musics.get(position).getAlbumpic();  
  6.         task.position = position;  
  7.         imageviews.add(task);  
  8.         // 通知工作线程可以下载图片了  
  9.         synchronized (workThread) {  
  10.             workThread.notify();  
  11.         }  

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


[java]  view plain  copy
  1. // handler  
  2.     private Handler handler = new Handler(){  
  3.         public void handleMessage(android.os.Message msg) {  
  4.             switch (msg.what) {  
  5.             case HANDLER_LOAD_IMAGEVIEW_SUCCESS:  
  6.                     // 更新UI  
  7.                     imageViewTask ivt = (imageViewTask) msg.obj;  
  8.                     ImageView iv = (ImageView) listview.findViewWithTag(ivt.position);  
  9.                     if(iv != null){  
  10.                         if(ivt.bitmap != null)  
  11.                             iv.setImageBitmap(ivt.bitmap);  
  12.                     }else{  
  13.                         iv.setImageResource(R.drawable.ic_launcher);  
  14.                     }  
  15.                   
  16.                 break;  
  17.   
  18.             }  
  19.         };  
  20.     };  


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

[java]  view plain  copy
  1. // 给imageview设置标记  
  2.         holder.iv.setTag(position);  
  3. // 增加任务队列  
  4.         imageViewTask task  = new imageViewTask();  
  5.         task.path = musics.get(position).getAlbumpic();  
  6.         task.position = position;  
  7.         imageviews.add(task);  
  8.         // 通知工作线程可以下载图片了  
  9.         synchronized (workThread) {  
  10.             workThread.notify();  
  11.         }  

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值