上一篇我們看了 DiskLruCache open 方法
這篇我們看看寫入緩存的過程

首先我們指定一個 cacheName 就是緩存的 key 來獲取一個 editor
點進去看一下實現(xiàn)過程

再點進 edit 中

首先看 checkNotClosed

通過判斷 journalWriter (Writer 類)是否為空來判斷是否完成寫入操作
在看 validateKey

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

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

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

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

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

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

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

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

如果需要 rebuild journalFile


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

屬性的注釋很清楚

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

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

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