Android进阶:Bitmap的高效加载和Cache,kotlinui组件

Bitmap bitmap = mBitmapLruCache.get(“1”);

ivBitamp.setImageBitmap(bitmap);

//删除缓存,一般不会用,因为快满时会自动删近期最少使用的缓存,就是它的核心功能

mBitmapLruCache.remove(“1”);

}

可见使用很简单,那么LruCache是怎么完成 删除“近期最少使用” 的呢?看下LruCache的代码:

public class LruCache<K, V> {

//此map以强引用的方式存储缓存对象

private final LinkedHashMap<K, V> map;

//当前缓存的大小(带单位的)

private int size;

//缓存最大容量(带单位的)

private int maxSize;

public LruCache(int maxSize) {

if (maxSize <= 0) {

throw new IllegalArgumentException(“maxSize <= 0”);

}

this.maxSize = maxSize;

//LinkedHashMap是按照 访问顺序 排序的,所以get、put操作都会把要存的k-v放在队尾

this.map = new LinkedHashMap<K, V>(0, 0.75f, true);

}

/**

  • 获取缓存,同时会把此k-v放在链表的尾部

*/

public final V get(K key) {

if (key == null) {

throw new NullPointerException(“key == null”);

}

V mapValue;

//get是线程安全的操作

synchronized (this) {

//LinkedHashMap的get方法中调afterNodeAccess,会移到链表尾部

mapValue = map.get(key);

if (mapValue != null) {

hitCount++;

return mapValue;

}

missCount++;

}

}

/**

  • 缓存key-value,value会存在 队尾

  • @return 之前也是这个key存的value

*/

public final V put(K key, V value) {

if (key == null || value == null) {

//不允许 null key、null value

throw new NullPointerException(“key == null || value == null”);

}

V previous;

//可见put操作是线程安全的

synchronized (this) {

putCount++;

size += safeSizeOf(key, value);

//强引用存入map(不会被动地被系统回收),其因为是LinkedHashMap,会放在队尾

previous = map.put(key, value);

if (previous != null) {

//如果前面已这个key,那么替换后调整下当前缓存大小

size -= safeSizeOf(key, previous);

}

}

if (previous != null) {

entryRemoved(false, key, previous, value);

}

//重新调整大小

trimToSize(maxSize);

return previous;

}

/**

  • 比较 当前已缓存的大小 和最大容量,决定 是否删除

*/

private void trimToSize(int maxSize) {

while (true) {

K key;

V value;

synchronized (this) {

if (size < 0 || (map.isEmpty() && size != 0)) {

throw new IllegalStateException(getClass().getName()

  • “.sizeOf() is reporting inconsistent results!”);

}

if (size <= maxSize) {

//大小还没超过最大值

break;

}

//已经达到最大容量

//因为是访问顺序,所以遍历的最后一个就是最近没有访问的,那么就可以删掉它了!

Map.Entry<K, V> toEvict = null;

for (Map.Entry<K, V> entry : map.entrySet()) {

toEvict = entry;

}

// END LAYOUTLIB CHANGE

if (toEvict == null) {

break;

}

key = toEvict.getKey();

value = toEvict.getValue();

map.remove(key);

size -= safeSizeOf(key, value);

evictionCount++;

}

//因为是为了腾出空间,所以这个回调第一个参数是true

entryRemoved(true, key, value, null);

}

}

protected void entryRemoved(boolean evicted, K key, V oldValue, V newValue) {}

}

由以上代码及注释,可见LruCache的算法实现是依靠 设置了访问顺序的LinkedHashMap。因为是访问顺序模式,get、put操作都会调整k-v到链表尾部。在缓存将满时,遍历LinkedHashMap,因为是访问顺序模式,所以遍历的最后一个就是最近没有使用的,然后删除即可。

2.2 DiskLruCache


DiskLruCache是实现磁盘缓存,所以需要设备存储的读写权限;一般是从网络请求图片后缓存到磁盘中,所以还需要网络权限。

DiskLruCache,不是官方提供,所以需要引入依赖:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值