带你了解Android常见的内存缓存算法

this.sizeLimit = sizeLimit;

cacheSize = new AtomicInteger();

if (sizeLimit > MAX_NORMAL_CACHE_SIZE) {

L.w(“You set too large memory cache size (more than %1$d Mb)”,

MAX_NORMAL_CACHE_SIZE_IN_MB);

}

}

@Override

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;

}

@Override

public Bitmap remove(String key) {

Bitmap value = super.get(key);

if (value != null) {

if (hardCache.remove(value)) {

cacheSize.addAndGet(-getSize(value));

}

}

return super.remove(key);

}

@Override

public void clear() {

hardCache.clear();

cacheSize.set(0);

super.clear();

}

protected int getSizeLimit() {

return sizeLimit;

}

protected abstract int getSize(Bitmap value);

protected abstract Bitmap removeNext();

}

LimitedMemoryCache所做的工作可以分为以下几步
  • 1) 保存着一份强引用

private final List hardCache = Collections.synchronizedList(

new LinkedList());

    1. 其实在我们调用put方法的时候,即我们把bitmap存进内存的时候,他会判断是否超出我们的最大值,超出我们的最大值就会调用removeNext();来获得我们将要移除的bitmap对象,最终再调用hardCache.remove(removedValue)去移除它。
    1. 注意到removeNext()方法是抽象方法,交给子类自己去实现自己的算法逻辑。

注意事项

结合BaseMemoryCache和LimitedMemoryCache,我们可以知道LimitedMemoryCache的子类,至少可以访问两份Bitmap 的缓存,一份是BaseMemoryCache所拥有的softMap ,是弱引用;一份是LimitedMemoryCachehar所拥有的hardCache 集合

//父类BaseMemoryCache的成员变量,并且每次在操作的时候都会把bitmap的弱引用存进去

private final Map<String, Reference> softMap = Collections.synchronizedMap(

new HashMap<String, Reference>());

//LimitedMemoryCache的成员变量,缓存的bitmap是强引用

private final List hardCache = Collections.synchronizedList(new LinkedList());

有人可能会有疑问了这些成员变量不是私有的吗?为什么说LimitedMemoryCache的子类,至少可以访问两份引用,这点我们可以从他们的put方法和get方法中知道,只需要调用super.put()即可把我们的bitmap缓存存到父类,调用super.get()即可从父类中 访问我们保存的Bitmap对象 。

@Override

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;

}

同理LimitedMemoryCache的子类put也会调用LimitedMemoryCache的put方法,代码见下面分析。

同时从上面的分析当中我们可以知道主要关心put和removeNext()这两个方法就可以了,put()方法其实就是把bitmap对象存进我们的queue队列中

下面我们在看一下UsingFreqLimitedMemoryCache是怎样实现的?

public class UsingFreqLimitedMemoryCache extends LimitedMemoryCache {

/**

  • Contains strong references to stored objects (keys) and last object usage date (in milliseconds). If hard cache

  • size will exceed limit then object with the least frequently usage is deleted (but it continue exist at

  • {@link #softMap} and can be collected by GC at any time)

*/

private fi

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值