ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
### Android里的内存缓存和磁盘缓存是怎么实现的。 内存缓存基于LruCache实现,磁盘缓存基于DiskLruCache实现。这两个类都基于Lru算法和LinkedHashMap来实现。 LRU算法可以用一句话来描述,如下所示: >LRU是Least Recently Used的缩写,最近最久未使用算法,从它的名字就可以看出,它的核心原则是如果一个数据在最近一段时间没有使用到,那么它在将来被 访问到的可能性也很小,则这类数据项会被优先淘汰掉。 LruCache的原理是利用LinkedHashMap持有对象的强引用,按照Lru算法进行对象淘汰。具体说来假设我们从表尾访问数据,在表头删除数据,当访问的数据项在链表中存在时,则将该数据项移动到表尾,否则在表尾新建一个数据项。当链表容量超过一定阈值,则移除表头的数据。 为什么会选择LinkedHashMap呢? 这跟LinkedHashMap的特性有关,LinkedHashMap的构造函数里有个布尔参数accessOrder,当它为true时,LinkedHashMap会以访问顺序为序排列元素,否则以插入顺序为序排序元素。 DiskLruCache与LruCache原理相似,只是多了一个journal文件来做磁盘文件的管理和迎神,如下所示: ``` libcore.io.DiskLruCache 1 1 1 DIRTY 1517126350519 CLEAN 1517126350519 5325928 REMOVE 1517126350519 ``` 注:这里的缓存目录是应用的缓存目录/data/data/pckagename/cache,未root的手机可以通过以下命令进入到该目录中或者将该目录整体拷贝出来: ```java //进入/data/data/pckagename/cache目录 adb shell run-as com.your.packagename cp /data/data/com.your.packagename/ //将/data/data/pckagename目录拷贝出来 adb backup -noapk com.your.packagename ``` 我们来分析下这个文件的内容: - 第一行:libcore.io.DiskLruCache,固定字符串。 - 第二行:1,DiskLruCache源码版本号。 - 第三行:1,App的版本号,通过open()方法传入进去的。 - 第四行:1,每个key对应几个文件,一般为1. - 第五行:空行 - 第六行及后续行:缓存操作记录。 第六行及后续行表示缓存操作记录,关于操作记录,我们需要了解以下三点: 1. DIRTY 表示一个entry正在被写入。写入分两种情况,如果成功会紧接着写入一行CLEAN的记录;如果失败,会增加一行REMOVE记录。注意单独只有DIRTY状态的记录是非法的。 2. 当手动调用remove(key)方法的时候也会写入一条REMOVE记录。 3. READ就是说明有一次读取的记录。 4. CLEAN的后面还记录了文件的长度,注意可能会一个key对应多个文件,那么就会有多个数字。