上一篇我們看了 DiskLruCache open 方法
這篇我們看看寫入緩存的過程
首先我們指定一個(gè) cacheName 就是緩存的 key 來獲取一個(gè) editor
點(diǎn)進(jìn)去看一下實(shí)現(xiàn)過程
再點(diǎn)進(jìn) edit 中
首先看 checkNotClosed
通過判斷 journalWriter (Writer 類)是否為空來判斷是否完成寫入操作
在看 validateKey
這里用正則表達(dá)式檢查 key 是否符合要求的格式 必須為數(shù)字或字母格式長(zhǎng)度在1~64位之間
繼續(xù)向下 sequenceNumber 在 edit 方法中傳入了固定的 ANY_SEQUENCE_NUMBER 我們暫且跳過
接下來判斷 entry 是否為空 entry 是在 linkedHashMap 中通過 key 來獲取的對(duì)象實(shí)體菌羽,如果不存在創(chuàng)建一個(gè)新的并存入 map
如果存在 并且 正在編輯中(外部已經(jīng)持有一個(gè) edit 對(duì)象) 返回空
接下來灶泵,在 entry 可用的情況下觅彰,創(chuàng)建一個(gè)新的 Editor 對(duì)象并將 entry 的編輯器 賦值
接下來在 journalFile 文件中寫入 dirty 記錄
返回 editor
接下來看看寫入數(shù)據(jù)過程
首先我將 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 匹配
不匹配拋出異常
接下來判斷 傳入的boolean 如果是成功 并且 entry.readable 是不可讀的
循環(huán) entry 內(nèi)的所有 value 判斷 written 標(biāo)志為 false
執(zhí)行 editor.abort() 方法并拋出異常 entry 沒有 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 中寫入 CLEAN 操作行
entry.sequenceNumber=nextSequenceNumber++ 這個(gè)還不清楚 稍后再看修械。
如果是失敗的的操作 在 journalFile 中寫入 REMOVE 操作行
寫入文件
判斷 當(dāng)前緩存容量 與 用戶設(shè)置的最大容量趾牧,或者是 rebuild 請(qǐng)求操作
如果需要 rebuild journalFile
循環(huán)刪除 lru 條件的 map entry
直到尺寸小于最大緩存容量
結(jié)束寫入流程
總結(jié)一下:
1、獲取 editor 時(shí) 會(huì)在 journal 中寫入一條 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 文件 說明
當(dāng)我們緩存數(shù)據(jù)時(shí) 是先將 editor 中流的數(shù)據(jù)寫入 dirty.tmp 中
確定后再轉(zhuǎn)到 cleanFile 中
我們回過頭在看一次 completeEdit()方法中的一段代碼
寫入數(shù)據(jù) commit 時(shí) 先判斷 dirty 是否存在东羹,也就是判斷一下之前是否有