DiskLruCache 源码解析 (三)—— 写入缓存

上一篇我们看了 DiskLruCache open 方法
这篇我们看看写入缓存的过程

image.png

首先我们指定一个 cacheName 就是缓存的 key 来获取一个 editor
点进去看一下实现过程

edit 方法

再点进 edit 中

image.png

首先看 checkNotClosed

image.png

通过判断 journalWriter (Writer 类)是否为空来判断是否完成写入操作
在看 validateKey

image.png

这里用正则表达式检查 key 是否符合要求的格式 必须为数字或字母格式长度在1~64位之间

image.png

继续向下 sequenceNumber 在 edit 方法中传入了固定的 ANY_SEQUENCE_NUMBER 我们暂且跳过
接下来判断 entry 是否为空 entry 是在 linkedHashMap 中通过 key 来获取的对象实体,如果不存在创建一个新的并存入 map
如果存在 并且 正在编辑中(外部已经持有一个 edit 对象) 返回空

image.png

接下来,在 entry 可用的情况下,创建一个新的 Editor 对象并将 entry 的编辑器 赋值
接下来在 journalFile 文件中写入 dirty 记录
返回 editor

image.png

接下来看看写入数据过程
首先我将 bitmap 转入 editor 的输出流中,然后调用了 editor.commit()方法

commit 方法

判断是否存在错误
如果存在错误 执行 completeEdit(editor,false) 并删除当前 entry
如果不存在错误 直接执行 completeEdit(editor,true)
设置 commited 为 true

completeEdit

image.png

首先进行判断 传入的 editor 对应的 entry 是否与传入的 editor 匹配
不匹配抛出异常
接下来判断 传入的boolean 如果是成功 并且 entry.readable 是不可读的
循环 entry 内的所有 value 判断 written 标志为 false
执行 editor.abort() 方法并抛出异常 entry 没有 value 值
在判断 entry 的 dirtyFile 是否存在 不存在执行 abort

image.png

再向下,遍历 entry 内的所有 value
如果执行成功的 completeEdit
将 entry 的 value 中 dirty 文件 转为 clean 文件 更改entry 长度、尺寸。
如果执行的失败的 completeEdit 删除 dirty 文件

image.png

继续向下 redundantOpCount 计数+1
置空当前 entry 的 editor
如果是成功的操作 在 journalFile 中写入 CLEAN 操作行
entry.sequenceNumber=nextSequenceNumber++ 这个还不清楚 稍后再看。
如果是失败的的操作 在 journalFile 中写入 REMOVE 操作行
写入文件
判断 当前缓存容量 与 用户设置的最大容量,或者是 rebuild 请求操作

image.png

如果需要 rebuild journalFile

callable 线程
trimToSize 方法

循环删除 lru 条件的 map entry
直到尺寸小于最大缓存容量
结束写入流程

总结一下:
1、获取 editor 时 会在 journal 中写入一条 dirty 记录
并在 lruMap 中创建/复用一个 entry
2、commit 方法 调用 completeEdit 方法 获取 dirtyfile 并转成 cleanfile
3、检查容量是否超出限制,如果超出执行整理操作,根据 lru 删除数据

我们还需要看一下 Entry类 这是一个 DiskLruCache 的内部类

Entry类

属性的注释很清楚

image.png

我们看方法列表中有两个熟悉的身影,getCleanFile() 和 getDirtyFile()

image.png

我们看到 cleanFile 是一个以 key 与 value 索引命名的文件
而 dirtyFile 是一个 tmp 文件 说明
当我们缓存数据时 是先将 editor 中流的数据写入 dirty.tmp 中
确定后再转到 cleanFile 中
我们回过头在看一次 completeEdit()方法中的一段代码

image.png

写入数据 commit 时 先判断 dirty 是否存在,也就是判断一下之前是否有

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,657评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,662评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,143评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,732评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,837评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,036评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,126评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,868评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,315评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,641评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,773评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,859评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,584评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,676评论 2 351

推荐阅读更多精彩内容