既然說Glide緩存那咱們得先知道緩存機制是啥?
宏觀上說主要分兩種緩存機制內(nèi)存緩存,磁盤緩存
使用內(nèi)存緩存原因:防止重復的把圖片讀入內(nèi)存,使其內(nèi)存資源浪費。
使用磁盤緩存原因:防止重復從網(wǎng)絡(luò)上或其他途徑下載和讀取的數(shù)據(jù),使其內(nèi)存資源浪費。
Glide三級緩存是啥呢?
內(nèi)存緩存,優(yōu)先加載,速度最快
本地緩存,次優(yōu)先加載,速度快
網(wǎng)絡(luò)緩存,最后加載,速度慢,浪費流量
Glide三級緩存那原理是啥?從寫入和讀取緩存的角度解析 Glide 的緩存
弱引用是啥?看此鏈接[https://blog.csdn.net/weixin_44819566/article/details/111170907]
映射是啥?看此鏈接[https://blog.csdn.net/mcryeasy/article/details/86741781]
雙向鏈表是啥?看此鏈接[https://baike.baidu.com/item/雙向鏈表/2968731?fr=aladdin]
HashMap是哈?看此鏈接http://m.itdecent.cn/p/dde9b12343c1
讀?。鹤x取緩存順序如下:
LruCache算法緩存 ------>到弱引用緩存----->進入磁盤緩存
加載圖片先從LruCache 去找看有沒有,如果有就放入WeakReference,如果沒有執(zhí)行下一步去WeakReference中找有沒有,有的話拿出來用,沒有在接著往下去找/磁盤緩存或者網(wǎng)路緩存
寫入:寫入緩存順序如下:
弱引用緩存 ------>LruCache算法緩存----->進入磁盤緩存
寫入先將圖片存入弱引用緩存,然后acpuired(圖片引用計數(shù)器)變量來記錄圖片被用的次數(shù)。
acpuired > 0 :圖片正在使用。
acpuired = 0 :圖片已經(jīng)沒有使用,然后接下來釋放資源,先將圖片從緩存中移除,put到LruResourceCache
這樣就做到了 如果圖片正在使用就要引用緩存,圖片已經(jīng)沒有使用就去LruCache算法緩存。
LruCache是啥意思呢?近期最少使用算法
按從近期訪問最少到近期訪問最多的順序(即訪問順序)來保存元素,LinkedHashMap提供了LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder)構(gòu)造函數(shù),該哈希映射的迭代順序就是最后訪問其條目的順序,這種映射很適合構(gòu)建LRU緩存。
以上是摘取別人的解釋轉(zhuǎn)換我的話語就是提前設(shè)定一個固定的緩存A 大小為10M,當緩存達到10M 將以前的舊數(shù)據(jù)移除,防止oom,LruCache內(nèi)部就是上面的LinkedHashMap通過映射存取數(shù)據(jù)
那么LinkedHashMap有具體是啥呢?
LinkedHashMap繼承于HashMap,HashMap是無序的,當我們想有順序地去存儲key-value時,就需要使用LinkedHashMap了且默認為插入順序。內(nèi)部利用的就是雙向鏈表結(jié)構(gòu)。
那在這里就可以提出一個問題,同一張照片放在不同尺寸的view控件上 Glide會只拿一張圖片緩存使用展示不同的view控件上嗎?
答案是不會的,如果仔細讀過我以前的Glide解析會發(fā)現(xiàn)這個里面存儲的值需要寬高兩個參數(shù),證明這個寬高是生成key的必要條件,Glide內(nèi)部如果是不同的尺寸Glide會重新加載一次,緩存兩張圖片!
那接著可以提出新的問題,如果Glide正在運行,突然殺死頁面(就是關(guān)閉)那這個頁面會內(nèi)存泄露嗎?
不會
這個地方你就可以考慮關(guān)聯(lián)到Glide的生命周期是綁定的,當時前面講的時候分兩種 ,
一種是在常用的Activity和Fragment上面:RequestManagerFragment(透明Fragment)加入FragmentManager中進行感知生命周期。
另一種在沒有生命周期的情況:,會采用Application 的生命周期貫穿整個應用,始終跟著applicationManager貫穿整個應用。
Glide磁盤緩存的讀寫
如果前面兩種緩存都沒有那么就進入磁盤緩存,內(nèi)存緩存有助于加快對最近查看過的位圖的訪問,但您不能依賴于此緩存中保留的圖片,如果你看了一個比較大數(shù)據(jù)集的組件很容易將內(nèi)存緩存填滿。您的應用可能被其他任務(如電話)中斷等,而在后臺時,應用可能會被終止,而內(nèi)存緩存則會銷毀。用戶恢復操作后,您的應用必須重新處理每張圖片所以必須磁盤緩存(DiskLruCache) 。DiskLruCache整體的思想跟LruCache是一樣的,也是利用了LinkedHashMap,但是DiskLruCache做了很多保護措施,DiskLruCache在各種對文件的操作上都將讀寫分開,為了怕寫失敗等情況,都是先嘗試寫在一個中間文件,成功再重命名回目標文件,其實DiskLruCache并沒有限制數(shù)據(jù)的緩存位置,可以自由地進行設(shè)定,但是通常情況下多數(shù)應用程序都會將緩存的位置選擇為 /sdcard/Android/data/<application package>/cache 這個路徑。選擇在這個位置有兩點好處:
第一,這是存儲在SD卡上的,因此即使緩存再多的數(shù)據(jù)也不會對手機的內(nèi)置存儲空間有任何影響,只要SD卡空間足夠就行。
第二,這個路徑被Android系統(tǒng)認定為應用程序的緩存路徑,當程序被卸載的時候,這里的數(shù)據(jù)也會一起被清除掉,這樣就不會出現(xiàn)刪除程序之后手機上還有很多殘留數(shù)據(jù)的問題。
在這推薦郭霖大神的一篇緩存博客:這里面說明了當上傳七牛云toekn 變化而導致的圖片緩存不能使用的解決辦法
https://guolin.blog.csdn.net/article/details/54895665
借鑒鏈接:[https://blog.csdn.net/qq_33565218/article/details/98970980]
借鑒鏈接:[https://guolin.blog.csdn.net/category_9268670.html]
.