上一篇我們看了 DiskLruCache open 方法
這篇我們看看寫(xiě)入緩存的過(guò)程

首先我們指定一個(gè) cacheName 就是緩存的 key 來(lái)獲取一個(gè) editor
點(diǎn)進(jìn)去看一下實(shí)現(xiàn)過(guò)程

再點(diǎn)進(jìn) edit 中

首先看 checkNotClosed

通過(guò)判斷 journalWriter (Writer 類)是否為空來(lái)判斷是否完成寫(xiě)入操作
在看 validateKey

這里用正則表達(dá)式檢查 key 是否符合要求的格式 必須為數(shù)字或字母格式長(zhǎng)度在1~64位之間

繼續(xù)向下 sequenceNumber 在 edit 方法中傳入了固定的 ANY_SEQUENCE_NUMBER 我們暫且跳過(guò)
接下來(lái)判斷 entry 是否為空 entry 是在 linkedHashMap 中通過(guò) key 來(lái)獲取的對(duì)象實(shí)體,如果不存在創(chuàng)建一個(gè)新的并存入 map
如果存在 并且 正在編輯中(外部已經(jīng)持有一個(gè) edit 對(duì)象) 返回空

接下來(lái),在 entry 可用的情況下,創(chuàng)建一個(gè)新的 Editor 對(duì)象并將 entry 的編輯器 賦值
接下來(lái)在 journalFile 文件中寫(xiě)入 dirty 記錄
返回 editor

接下來(lái)看看寫(xiě)入數(shù)據(jù)過(guò)程
首先我將 bitmap 轉(zhuǎn)入 editor 的輸出流中,然后調(diào)用了 editor.commit()方法

判斷是否存在錯(cuò)誤
如果存在錯(cuò)誤 執(zhí)行 completeEdit(editor,false) 并刪除當(dāng)前 entry
如果不存在錯(cuò)誤 直接執(zhí)行 completeEdit(editor,true)
設(shè)置 commited 為 true
completeEdit

首先進(jìn)行判斷 傳入的 editor 對(duì)應(yīng)的 entry 是否與傳入的 editor 匹配
不匹配拋出異常
接下來(lái)判斷 傳入的boolean 如果是成功 并且 entry.readable 是不可讀的
循環(huán) entry 內(nèi)的所有 value 判斷 written 標(biāo)志為 false
執(zhí)行 editor.abort() 方法并拋出異常 entry 沒(méi)有 value 值
在判斷 entry 的 dirtyFile 是否存在 不存在執(zhí)行 abort

再向下,遍歷 entry 內(nèi)的所有 value
如果執(zhí)行成功的 completeEdit
將 entry 的 value 中 dirty 文件 轉(zhuǎn)為 clean 文件 更改entry 長(zhǎng)度、尺寸。
如果執(zhí)行的失敗的 completeEdit 刪除 dirty 文件

繼續(xù)向下 redundantOpCount 計(jì)數(shù)+1
置空當(dāng)前 entry 的 editor
如果是成功的操作 在 journalFile 中寫(xiě)入 CLEAN 操作行
entry.sequenceNumber=nextSequenceNumber++ 這個(gè)還不清楚 稍后再看。
如果是失敗的的操作 在 journalFile 中寫(xiě)入 REMOVE 操作行
寫(xiě)入文件
判斷 當(dāng)前緩存容量 與 用戶設(shè)置的最大容量,或者是 rebuild 請(qǐng)求操作

如果需要 rebuild journalFile


循環(huán)刪除 lru 條件的 map entry
直到尺寸小于最大緩存容量
結(jié)束寫(xiě)入流程
總結(jié)一下:
1、獲取 editor 時(shí) 會(huì)在 journal 中寫(xiě)入一條 dirty 記錄
并在 lruMap 中創(chuàng)建/復(fù)用一個(gè) entry
2、commit 方法 調(diào)用 completeEdit 方法 獲取 dirtyfile 并轉(zhuǎn)成 cleanfile
3、檢查容量是否超出限制,如果超出執(zhí)行整理操作,根據(jù) lru 刪除數(shù)據(jù)
我們還需要看一下 Entry類 這是一個(gè) DiskLruCache 的內(nèi)部類

屬性的注釋很清楚

我們看方法列表中有兩個(gè)熟悉的身影,getCleanFile() 和 getDirtyFile()

我們看到 cleanFile 是一個(gè)以 key 與 value 索引命名的文件
而 dirtyFile 是一個(gè) tmp 文件 說(shuō)明
當(dāng)我們緩存數(shù)據(jù)時(shí) 是先將 editor 中流的數(shù)據(jù)寫(xiě)入 dirty.tmp 中
確定后再轉(zhuǎn)到 cleanFile 中
我們回過(guò)頭在看一次 completeEdit()方法中的一段代碼

寫(xiě)入數(shù)據(jù) commit 時(shí) 先判斷 dirty 是否存在,也就是判斷一下之前是否有