android LruCache内存缓存源码解析

来源:互联网 发布:免费虚拟主机空间php 编辑:程序博客网 时间:2024/06/05 22:42

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

先看下 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;}

晚上写

0 0
原创粉丝点击