Android开发

Glide都在用的LruCache,你会几分?

本文主要是介绍Glide都在用的LruCache,你会几分?,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

前言

说到Glide就有点尴尬,我本来想出一篇《手撕Glide》,但是很遗憾,源码实在太多了。写着写着就3000多字了,甚至还没写完,实在不合适,因为我写文的原则是短小精悍,所以就暂时不出这篇文章了,这次就先讲讲Glide都在用的LruCache有什么神奇之处。另外我抖音的面试在即,也不知道自己水平到了没有,现在出一篇算一篇先。

思维导图

使用方法及结果

在项目中直接导入Glide的库,调用内部的LruCache来看看效果。

LruCache lruCache = new LruCache<String, Integer>(2);
lruCache.put("1", 1);
lruCache.put("2", 2);
lruCache.put("1", 1);
lruCache.put("3", 3);
System.out.println(lruCache.get("1"));
System.out.println(lruCache.get("2"));
System.out.println(lruCache.get("3"));
复制代码

简要说明代码内容,创建一个空间为2的存储空间(这里先不透漏内部结构),用put()方法对数据进行存储,再通过get()对每个数据进行一次获取操作,然后我们再来看看结果。

我的天!!2没了? 这是怎么一回事??为了知道答案,那我们只好进入Glide的库中看看原因了。

LruCache源码导读

先看看LruCache的变量家庭里有哪些小家伙把。

public class LruCache<T, Y> {
  // 容量为100的双向链表
  private final Map<T, Y> cache = new LinkedHashMap<>(100, 0.75f, true); 
  private final long initialMaxSize; // 初始化最大容量
  private long maxSize; // 最大容量
  private long currentSize; // 已存在容量
}
复制代码

同样对于LruCache来说不也和HashMap一样只有三步骤要走嘛,那我就从这三个步骤入手探索一下LruCache好了,但是我们要带上一个问题出发initialMaxSize的作用是什么?

new LruCache<T, Y>(size)

  public LruCache(long size) {
    this.initialMaxSize = size;
    this.maxSize = size;
  }
复制代码

到这里想来读者都已经知道套路了,也就初始化了初始化最大容量和最大容量,那就直接下一步。

put(key, value)

public synchronized Y put(@NonNull T key, @Nullable Y item) {
    // 返回值就是一个1
    final int itemSize = getSize(item);
    // 如果1大于等于最大值就无操作
    // 也就说明整个初始化的时候并不能将size设置成1
    if (itemSize >= maxSize) {
      //用于重写的保留方法
      onItemEvicted(key, item);
      return null;
    }
    // 对当前存在数据容量加一
    if (item != null) {
      currentSize += itemSize;
    }
    @Nullable final Y old = cache.put(key, item);
    if (old != null) {
      currentSize -= getSize(old);
    
      if (!old.equals(item)) {
        onItemEvicted(key, old);
      }
    }
    evict(); // 1 -->

    return old;
  }
// 由注释1直接调用的方法
private void evict() {
    trimToSize(maxSize); // 2 -->
  }
// 由注释2直接调用的方法 
protected synchronized void trimToSize(long size) {
    Map.Entry<T, Y> last;
    Iterator<Map.Entry<T, Y>> cacheIterator;
    // 说明当前的容量大于了最大容量
    // 需要对最后的数据进行一个清理
    while (currentSize > size) {
      cacheIterator = cache.entrySet().iterator();
      last = cacheIterator.next();
      final Y toRemove = last.getValue();
      currentSize -= getSize(toRemove);
      final T key = last.getKey();
      cacheIterator.remove();
      onItemEvicted(key, toRemove);
    }
  }
复制代码

这是一个带锁机制的方法,通过对当前容量和最大容量的判断,来抉择是否需要把我们的数据进行一个删除。但是问题依旧存在,initialMaxSize的作用是什么?,我们能够知道的是maxSize是一个用于控制容量大小的值。

get()

 public synchronized Y get(@NonNull T key) {
    return cache.
                    
这篇关于Glide都在用的LruCache,你会几分?的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!