前面的两篇文章着重介绍的是磁盘缓存,这篇文章主要是讲解一下内存缓存。对于内存缓存,也打算分两篇文章来进行讲解。在这一篇文章中,我们主要是关注三个类,
MemoryCache、BaseMemoryCache以及LimitedMemoryCache。
首先我们先看一下内存缓存的接口MemoryCache。
[java] view plaincopyprint?
- put(String key, Bitmap value);
- Bitmap get(String key);
- Bitmap remove(String key);
- Collection<String> keys();
- void clear();
从上面可以看出,整体的接口的设计分为5个方法,1、存入真正的Bitmap 2、通过键获取Bitmap 3、通过键删除Bitmap 4、迭代获取所有的键的集合 5、清空内存的缓存。
接下来我们看实现内存缓存的接口的抽象类BaseMemoryCache。
与前面的文章一样,还是先从变量入手。
[java] view plaincopyprint?
- /** Stores not strong references to objects */
- private final Map<String, Reference<Bitmap>> softMap = Collections.synchronizedMap(new HashMap<String, Reference<Bitmap>>());
正如所说的那样,这个变量是存储非强引用的对象。
稍微的关注一下下面的方法
[java] view plaincopyprint?
- @Override
- public Bitmap get(String key) {
- Bitmap result = null;
- Reference<Bitmap> reference = softMap.get(key);
- if (reference != null) {
- result = reference.get();
- }
- return result;
- }
通过键获取软引用中的数值Bitmap。
最后我们来看一下有限内存缓存空间的缓存类LimitedMemoryCache,从继承关系上来看,它是对BaseMemoryCache的进一步扩展。
从变量上来看:
[java] view plaincopyprint?
- private static final int MAX_NORMAL_CACHE_SIZE_IN_MB = 16;
- private static final int MAX_NORMAL_CACHE_SIZE = MAX_NORMAL_CACHE_SIZE_IN_MB * 1024 * 1024;
- private final int sizeLimit;
- private final AtomicInteger cacheSize;
- private final List<Bitmap> hardCache = Collections.synchronizedList(new LinkedList<Bitmap>());
从变量的定义来看,包括最大的缓存的限制,当前的缓存的尺寸以及强引用对象的集合。
拿其中的对象的存储的方法来分析一下:
[java] view plaincopyprint?
- public boolean put(String key, Bitmap value) {
- boolean putSuccessfully = false;
- // Try to add value to hard cache
- int valueSize = getSize(value);
- int sizeLimit = getSizeLimit();
- int curCacheSize = cacheSize.get();
- if (valueSize < sizeLimit) {
- while (curCacheSize + valueSize > sizeLimit) {
- Bitmap removedValue = removeNext();
- if (hardCache.remove(removedValue)) {
- curCacheSize = cacheSize.addAndGet(-getSize(removedValue));
- }
- }
- hardCache.add(value);
- cacheSize.addAndGet(valueSize);
- putSuccessfully = true;
- }
- // Add value to soft cache
- super.put(key, value);
- return putSuccessfully;
- }
很明显,在缓存图片的时候,先需要判断一下当前的图片的加入有没有超过整体的缓存的内存的尺寸的限制。如果超过,先根据不同的策略,删除优先需要删除的图片,如果合适,当前的图片插入,如果不合适,继续迭代。
时间: 2024-10-10 00:51:00