Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1540584
  • 博文数量: 113
  • 博客积分: 3526
  • 博客等级: 中校
  • 技术积分: 1815
  • 用 户 组: 普通用户
  • 注册时间: 2009-09-08 09:46
个人简介

记录总结自己的工作

文章分类

全部博文(113)

文章存档

2015年(19)

2014年(10)

2013年(6)

2012年(16)

2011年(24)

2010年(21)

2009年(17)

分类: Android平台

2013-04-19 10:09:06

       在android中ListView使用得很多,而且经常会显示一些图片,这些图片要么要从网上下载,要不就要处理一下本地的图片,产生一个缩略图。为了避免ANR和OOM,创建一个工具类,使用二级缓存来异步加载图片。


点击(此处)折叠或打开

  1. public class CacheImageLoader {

  2.     // 缓存的大小

  3.     private static final int MAX_CAPACITY = 15;
  4.     // 二级缓存

  5.     private static ConcurrentHashMap<String, SoftReference<Drawable>> mSoftCache = new ConcurrentHashMap<String, SoftReference<Drawable>>(
  6.             MAX_CAPACITY / 2);
  7.     // 一级缓存

  8.     private static HashMap<String, Drawable> mHardCache = new LinkedHashMap<String, Drawable>(
  9.             MAX_CAPACITY / 2, 0.75f, true) {
  10.         private static final long serialVersionUID = 1L;

  11.         protected boolean removeEldestEntry(Entry<String, Drawable> eldest) {
  12.             if (size() > MAX_CAPACITY) {
  13.                 // 将较少用到的图片从一级缓存挪到二级缓存中

  14.                 mSoftCache.put(eldest.getKey(), new SoftReference<Drawable>(
  15.                         eldest.getValue()));
  16.                 return true;
  17.             }
  18.             return false;
  19.         };
  20.     };

  21.     public void CacheImageClear() {
  22.         mHardCache.clear();
  23.         mSoftCache.clear();
  24.     }

  25.     public Drawable getDrawableFromCache(String url) {
  26.         Drawable drawable = null;
  27.         synchronized (mHardCache) {
  28.             drawable = mHardCache.get(url);
  29.             if (drawable != null) {
  30.                 // 类似LRU,将最近使用的图片放到最前面

  31.                 mHardCache.remove(url);
  32.                 mHardCache.put(url, drawable);
  33.                 return drawable;
  34.             }
  35.         }
  36.         // 一级级缓存中没有找到,在二级缓存中查找

  37.         SoftReference<Drawable> softReference = mSoftCache.get(url);
  38.         if (softReference != null) {
  39.             drawable = softReference.get();
  40.             if (drawable == null) {
  41.                 mSoftCache.remove(url);
  42.             }

  43.         }
  44.         return drawable;
  45.     }

  46.     public Drawable loadDrawable(final String imageUrl,
  47.             final ImageCallback imageCallback) {

  48.         Drawable drawable = getDrawableFromCache(imageUrl);
  49.         if (null != drawable) {
  50.             return drawable;
  51.         } else {
  52.             final Handler handler = new Handler() {
  53.                 public void handleMessage(Message message) {
  54.                     if (null != imageUrl && null != message
  55.                             && null != imageCallback && null != message.obj) {
  56.                         try {
  57.                             // 图片异步加载完后,通知主线程更新

  58.                             imageCallback.imageLoaded((Drawable) message.obj,
  59.                                     imageUrl);
  60.                         } catch (Exception e) {
  61.                             e.printStackTrace();
  62.                         }
  63.                     }
  64.                 }
  65.             };

  66.             // 缓存中没有图片,开启线程异步加载图片

  67.             new Thread() {
  68.                 @Override
  69.                 public void run() {
  70.                     if (null != imageUrl) {
  71.                         Drawable drawable = Util.createImageDrawable(imageUrl);
  72.                         if (null != drawable) {
  73.                             addImage2Cache(imageUrl, drawable);
  74.                             Message message = handler
  75.                                     .obtainMessage(0, drawable);
  76.                             handler.sendMessage(message);
  77.                         }
  78.                     }
  79.                 }
  80.             }.start();

  81.         }

  82.         return null;
  83.     }

  84.     public void addImage2Cache(String url, Drawable value) {
  85.         if (value == null || url == null) {
  86.             return;
  87.         }
  88.         synchronized (mHardCache) {
  89.             mHardCache.put(url, value);
  90.         }
  91.     }

  92.     public interface ImageCallback {
  93.         public void imageLoaded(Drawable imageDrawable, String imageUrl);
  94.     }
  95. }

如何使用呢?在getView方法里直接就可以调用了


点击(此处)折叠或打开

  1. Drawable cachedImage = cacheImageLoader.loadDrawable(path,
  2.                         new CacheImageLoader.ImageCallback() {

  3.                             @Override
  4.                             public void imageLoaded(Drawable imageDrawable,
  5.                                     String imageUrl) {
  6.                                 if (imageDrawable != null) {
  7.                                     holder.imageView
  8.                                             .setBackgroundDrawable(imageDrawable);
  9.                                 }
  10.                             }

  11.                         });
  12.                 if (cachedImage == null) {
  13.                     holder.imageView
  14.                             .setBackgroundResource(R.drawable.singer);
  15.                 } else {
  16.                     holder.imageView.setBackgroundDrawable(cachedImage);
  17.                 }


这个工具类基本上就可以满足一般的需求了。想要进一步改进可以加入线程池或者在ListView中加入OnScrollListener,仅在停止滑动的时候加载图片等。
阅读(3530) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~