androidimageloader框架之图片缓存
Android ImageLoader框架之图片缓存 在教你写Android ImageLoader框架系列博文中,我们从基本架构 到具体实现已经更新了大部分的内容。今天,我们来讲最后一个关 键点,即图片的缓存。为了用户体验,通常情况下我们都会将已经 下载的图片缓存起来,一般来说内存和本地都会有图片缓存。那既 然是框架,必然需要有很好的定制性,这让我们又自然而然的想到 了抽象。下面我们就一起来看看缓存的实现吧。 缓存接口 在教你写Android ImageLoader框架之图片加载与加载策略我们聊 到了Loader,然后阐述了AbsLoader的基本逻辑,其中就有图片缓 存。因此AbsLoader中必然含有缓存对象的引用。我们看看相关代 码 /*** author mrsimple*/ public abstract class AbsLoader implements Loader { /*** 图片缓存*/private static BitmapCache mCache SimpleImageLoader.getInstance.getConfig.bitma pCache;// 代码省略 } 1 2 3 4 5 6 7 8 9 10 11 12 AbsLoader中定义了一个static的BitmapCache对象,这个就是图 片缓存对象。那为什么是static呢因为不管Loader有多少个,缓 存对象都应该是共享的,也就是缓存只有一份。说了那么多,那我 们先来了解一下BitmapCache吧。 public interface BitmapCache { public Bitmap getBitmapRequest key;public void putBitmapRequest key, Bitmap value;public void removeBitmapRequest key; } 1 2 3 4 5 6 7 8 9 BitmapCache很简单,只声明了获取、添加、移除三个方法来操作 图片缓存。这里有依赖了一个BitmapRequest类,这个类代表了一 个图片加载请求,该类中有该请求对应的ImageView、图片uri、显 示Config等属性。在缓存这块我们主要要使用图片的uri来检索缓存 中是否含有该图片,缓存以图片的uri为key,Bitmap为value来关联 存储。另外需要BitmapRequest的ImageView宽度和高度,以此来 按尺寸加载图片。定义BitmapCache接口还是为了可扩展性,面向接口的编程的理念 又再一次的浮现在你面前。如果是你,你会作何设计呢自己写代 码来练习一下吧,看看自己作何考虑,如果实现,这样你才会从中 有更深的领悟。 内存缓存 既然是框架,那就需要接受用户各种各样的需求。但通常来说框架 会有一些默认的实现,对于图片缓存来说内存缓存就其中的一个默 认实现,它会将已经加载的图片缓存到内存中,大大地提升图片重 复加载的速度。内存缓存我们的策略是使用LRU算法,直接使用了 support.v4中的LruCache类,相关代码如下。 /*** 图片的内存缓存,key为图片的uri,值为图片本身* * author mrsimple*/ public class MemoryCache implements BitmapCache {private LruCache mMemeryCache; public MemoryCache {// 计算可使用的最大内存final int maxMemory int Runtime.getRuntime.maxMemory / 1024;// 取4分之一的可用内存作为缓存final int cacheSize maxMemory / 4;mMemeryCache new LruCachecacheSize {Overrideprotected int sizeOfString key, Bitmap bitmap {return bitmap.getRowBytes * bitmap.getHeight / 1024;}};}Overridepublic Bitmap getBitmapRequest key {return mMemeryCache.getkey.imageUri;}Overridepublic void putBitmapRequest key, Bitmap value {mMemeryCache.putkey.imageUri, value;} Overridepublic void removeBitmapRequest key {mMemeryCache.removekey.imageUri;} } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 2627 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 就是简单的实现了BitmapCache接口,然后内部使用LruCache类 实现内存缓存。比较简单,就不做说明了。 sd卡缓存 对于图片缓存,内存缓存是不够的,更多的需要是将图片缓存到sd 卡中,这样用户在下次进入app时可以直接从本地加载图片,避免 重复地从网络上读取图片数据,即耗流量,用户体验又不好。sd卡缓存我们使用了Jake Wharton的DiskLruCache类,我们的sd卡缓 存类为DiskCache,代码如下 public class DiskCache implements BitmapCache {/*** 1MB*/private static final int MB 1024 * 1024;/*** cache dir*/private static final String IMAGE_DISK_CACHE “bitmap“;/*** Disk LRU Cache*/private DiskLruCache mDiskLruCache;/*** Disk Cache Instance*/private static DiskCache mDiskCache;/*** param context*/private DiskCacheContext context {initDiskCachecontext;}