异步下载图片,同时下载多张图片

对于进行多线程异步处理的同学应该有很大帮助,先把原帖链接拿过来:http://www.eoeandroid.com/thread-210082-1-1.html下面上我测试后的截图,五张图片,一次下载完成。如果使用handler+Thread+MessageQueen的话,必须要等到一张图片下载完成,线程处于空闲状态才能下载第二幅图片。这个实例使用的是Handler+ExecutorService(线程池)+MessageQueue+本地缓存模式。他的好处是多个图片可以一次下载完成,线程直接是异步的,增加本地缓存模式可以有效放在重复下载已经下载完成的图片,节省手机内存空间,同时提高了想效率

源代码如下:

核心代码,多线程异步下载加双缓存:

package com.marller.asyncimageloader;

import java.lang.ref.SoftReference;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import android.graphics.drawable.Drawable;
import android.os.Handler;

public class AsyncImageLoader {

 private Map<String, SoftReference<Drawable>> imageCache = new HashMap<String, SoftReference<Drawable>>();
 private ExecutorService mExeCutorService = Executors.newFixedThreadPool(5);
 private final Handler handler = new Handler();

 public Drawable getDrawable(final String imageUrl,
   final ImageCallback callback) {
  // 如果缓存过就从缓存中取出数据
  if (imageCache.containsKey(imageUrl)) {
   SoftReference<Drawable> softReference = imageCache.get(imageUrl);
   if (softReference.get() != null) {
    return softReference.get();
   }
  }
  // 缓存中没有图像,则从网络上取出数据,并将取出的数据缓存到内存中
  mExeCutorService.submit(new Runnable() {
   public void run() {
    try {
     final Drawable drawable = loadImageFromUrl(imageUrl);

     imageCache.put(imageUrl, new SoftReference<Drawable>(
       drawable));

     handler.post(new Runnable() {
      public void run() {
       callback.imageLoaded(drawable);
      }
     });
    } catch (Exception e) {
     throw new RuntimeException(e);
    }
   }
  });
  return null;
 }

 // 从网络上取数据方法
 protected Drawable loadImageFromUrl(String imageUrl) {
  try {
   return Drawable.createFromStream(new URL(imageUrl).openStream(),
     "image.jpg");

  } catch (Exception e) {
   throw new RuntimeException(e);
  }
 }

 // 对外界开放的回调接口
 public interface ImageCallback {
  // 注意 此方法是用来设置目标对象的图像资源
  public void imageLoaded(Drawable imageDrawable);
 }
}

 

 

 

利用上面的下载公爵开始测试:

package com.marller.asyncimageloader;

import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.widget.ImageView;

public class MainActivity extends Activity {

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  loadImage(
    "http://a.hiphotos.baidu.com/image/q%3D100%3Ba0%3D+%2C1%2C1/sign=e02416c1c1fdfc03e378e7b8e404e6a4/eac4b74543a98226e724cb188882b9014a90eb2c.jpg",
    R.id.imageView1);
  loadImage(
    "http://b.hiphotos.baidu.com/image/q%3D85%3Ba0%3D+%2C1%2C1/sign=f8f331ac4ec2d562f408dde8dc70a0d2/d833c895d143ad4b90d8d90c83025aafa50f0603.jpg",
    R.id.imageView2);
  loadImage(
    "http://e.hiphotos.baidu.com/image/q%3D100%3Ba0%3D+%2C1%2C1/sign=69d9640f38f33a87986d041af6677108/cf1b9d16fdfaaf514f3e66808e5494eef01f7a34.jpg",
    R.id.imageView3);
  loadImage(
    "http://d.hiphotos.baidu.com/pic/w%3D230/sign=42483bc35266d0167e19992ba72ad498/f703738da9773912c8883d6ff8198618367ae216.jpg",
    R.id.imageView4);
  loadImage(
    "http://b.hiphotos.baidu.com/pic/w%3D230/sign=b19458e464380cd7e61ea5ee9145ad14/f2deb48f8c5494eef1f5a84d2cf5e0fe98257e8a.jpg",
    R.id.imageView5);
 }

 private AsyncImageLoader asyncImageLoader = new AsyncImageLoader();

 // 引入线程池,并引入内存缓存功能,并对外部调用封装了接口,简化调用过程
 private void loadImage(final String url, final int id) {
  // 如果缓存过就会从缓存中取出图像,ImageCallback接口中方法也不会被执行
  Drawable cacheImage = asyncImageLoader.getDrawable(url,
    new AsyncImageLoader.ImageCallback() {
     // 请参见实现:如果第一次加载url时下面方法会执行
     public void imageLoaded(Drawable imageDrawable) {
      ((ImageView) findViewById(id))
        .setImageDrawable(imageDrawable);
     }
    });
  if (cacheImage != null) {
   ((ImageView) findViewById(id)).setImageDrawable(cacheImage);
  }
 }
}

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值