欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2023-11-07 15:56:46
android 实现单线程轮循机制批量下载图片 listview 在为item 添加从网上下载下来的图片时, 如果每次都整合一个item时都需要new一个thread去下...

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

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 )才会终止

// 获得图片bitmap 
  workthread = new thread(){ 
   public void run() { 
    while(isloop){ 
     if(!imageviews.isempty()){ 
      try { 
       message msg = new message(); 
   // 获得图片的bitmap 
       msg.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()方法 

// 获得图片的bitmap 
   private 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

// handler 
 private handler handler = new handler(){ 
  public void handlemessage(android.os.message msg) { 
   switch (msg.what) { 
   case handler_load_imageview_success: 
     // 更新ui 
     imageviewtask 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; 
 
   } 
  }; 
 }; 



以上就是使用android 批量下载图片的讲解,如有疑问请留言或者到本站社区进行交流讨论,大家共同进步,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!