软件编程
位置:首页>> 软件编程>> Android编程>> Android 实现单线程轮循机制批量下载图片

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

作者:小_练  发布时间:2022-11-05 11:03:45 

标签:Android,单线程,下载图片

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;

}
 };
};

来源:http://blog.csdn.net/qq_21046135/article/details/50670252

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com