美文网首页
图片缓存/内存缓存/LruCache

图片缓存/内存缓存/LruCache

作者: 官先生Y | 来源:发表于2017-01-13 16:17 被阅读216次

    三级缓存

    内存缓存

    我们的缓存容量是有限的,它会面临一个问题:当有新的内容需要加入我们的缓存,但我们的缓存空闲的空间不足以放进新的内容时,如何舍弃原有的部分内容从而腾出空间用来放新的内容?

    解决这个问题的算法有多种,比如LRU,LFU,FIFO等

    • 官方推荐使用LRU并且Google在SDK中为我们提供对LRU算法的实现类android.util.LruCache。
    • 需要注意区分的是LRU和LFU。
      • 前者是最近最少使用,即淘汰最长时间未使用的对象;以时间为参考。
      • 后者是最不频繁使用,即淘汰一段时间内使用最少的对象。以使用过次数为参考。
      • 例子:比如我们缓存对象的顺序是:A B C B D A C A,当需要淘汰一个对象时
        • 如果采用LRU算法,则淘汰的是B,因为它是最长时间未被使用的
        • 如果采用LFU算法,则淘汰的是D,因为在这段时间内它只被使用了一次,是最不经常使用的。
    • 图片的内存缓存基于LruCache类,类LruCache实现LRU算法缓存置换策略,LRU算法基于LinkedHashMap类,LinkedHashMap基于数据结构之双向循环链表。

    小结:
    不论图片的内存缓存算法是哪一种,这些算法解决的是超出最大值时如何自动回收的问题。

    LinkedHashMap

    是什么?

    LinkedHashMap继承自HashMap,不同的是,它是一个双向循环链表,它的每一个数据结点都有两个指针,分别指向直接前驱和直接后继。

    成员变量accessOrder
    • accessOrder是指定它的排序方式,当它为false时,只按插入的顺序排序,即新放入的元素会在链表的尾部;
    • 而当它为true时,更新或访问某个节点的数据时,这个对应的结点也会被放到尾部。

    问题

    LruCache怎么知道添加完新元素后是否超过总缓存?

    添加新元素后,先调用sizeOf()计算元素大小,在与当前缓存大小相加得到新的缓存大小,最后调用trimMemory()检查并修剪内存。

    当添加新元素会超过总缓存,那么怎么基于最近最少使用算法移除元素?

    while循环,通过不断调用LinkedHashMap.eldest()获得头节点指向下一个节点(最老节点),然后LinkedHashMap.remove()将其移出,在计算缓存大小,直到缓存大小小于总大小,循环结束。

    Android源码解析——LruCache


    MyBitmapUtils.display(ImageView ivPic, String url)

    • 提供给外部进行图片显示和图片缓存的接口
    • 封装了对图片进行三级缓存逻辑

    NetCacheUtils. getBitmapFromNet(ImageView ivPic, String url)

    • 提供给外部从网络获取Bitmap的接口
    • 封装了从网络获取图片并缓存本地和内存的细节

    LocalCacheUtils

    MemoryCacheUtils

    • Android 虚拟机默认分配给每个App 固定大小的内存空间。
    • 图片大小 = 图片的总像素 * 每个像素占用的大小
      例如一张1920x1080的JPG图片,在Android 系统中是以ARGB格式解析的,即一个像素需占用4个字节,图片的大小=1920x1080x4=7M。

    Android中图片的三级缓存

    相关文章

      网友评论

          本文标题:图片缓存/内存缓存/LruCache

          本文链接:https://www.haomeiwen.com/subject/hsesbttx.html