android LruCache内存缓存源码解析

我们在做图片加载的时候,都是使用了磁盘缓存或者内存缓存,这是必须必须的,今天就讲下内存缓存,它的里层是怎么实现的,可能比你想象的要简单,

先看下 LruCache几个变量的定义:

private final LinkedHashMap<K, V> map;

/** Size of this cache in units. Not necessarily the number of elements. */
private int size;
private int maxSize;

private int putCount;
private int createCount;
private int evictionCount;
private int hitCount;
private int missCount;

它定义了一个LinkedHashMap来维护加载的图片,使用LinkedHashMap集合的好处在于它是有序的,然后看下这个类的构造是什么样的,

/**
 * @param maxSize for caches that do not override {@link #sizeOf}, this is
 *     the maximum number of entries in the cache. For all other caches,
 *     this is the maximum sum of the sizes of the entries in this cache.
 */
public LruCache(int maxSize) {
    if (maxSize <= 0) {
        throw new IllegalArgumentException("maxSize <= 0");
    }
    this.maxSize = maxSize;
    this.map = new LinkedHashMap<K, V>(0, 0.75f, true);
}

构造传递的是准备开辟多少内存给加载图片,但是得计算每个图片所占的内存大小啊,不然到时候怎么知道加载图片的总数内存和你分配的内存做比较,

/**
 * Returns the size of the entry for {@code key} and {@code value} in
 * user-defined units.  The default implementation returns 1 so that size
 * is the number of entries and max size is the maximum number of entries.
 *
 * <p>An entry's size must not change while it is in the cache.
 */
protected int sizeOf(K key, V value) {
    return 1;
}

在创建对象的时候重写这个方法就可以了,然后就是看put方法了,

/**
 * Caches {@code value} for {@code key}. The value is moved to the head of
 * the queue.
 *
 * @return the previous value mapped by {@code key}.
 */
public final V put(K key, V value) {
    if (key == null || value == null) {//对传递进来的K,V进行容错判断
        throw new NullPointerException("key == null || value == null");
    }

    V previous;//临时保存V值,一般都是Bitmap
    synchronized (this) {//
        putCount++;//计算图片的数量
        size += safeSizeOf(key, value);//计算图片所占内存大小  size是积累所有加载图片所占内存的大小
        previous = map.put(key, value);
        if (previous != null) {//判断这个之前内存加载过,如果加载过了,内存就不应该把刚之前算的内存所占大小加进去
            size -= safeSizeOf(key, previous);
        }
    }

    if (previous != null) {
        entryRemoved(false, key, previous, value);//
    }

    trimToSize(maxSize);
    return previous;
}

晚上写

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值