聊聊Glide緩存機制
緩存機制簡介
1、緩存的圖片資源
原始圖片(Source) :即圖片源的圖片初始大小和分辨率;
轉換后的圖片(Result) :經過尺寸縮放和大小壓縮等處理后的圖片;
當使用Glide加載圖片時,Glide會默認根據View視圖對圖片進行壓縮和轉換,而不顯示原始圖。(這也是Glide加載速度高于Picasso的原因)
2、緩存機制設計
Glide的緩存功能設計成二級緩存:內存緩存和硬盤緩存。(從網絡加載不屬于緩存)
內存緩存:防止重復將圖片讀入到內存,造成內存資源浪費,只緩存轉換后的圖片,而不是原始圖片;
磁盤緩存:防止重復從網絡或其他地方下載和讀取數據,可緩存原始圖片和轉換過后的圖片,用戶自行設置;
在Glide中,緩存的讀取順序為:內存緩存 –> 磁盤緩存 –> 網絡 ,內存緩存和磁盤緩存相互不影響,獨立配置,內存緩存是默認開啟的。
Glide的緩存機制使得Glide具備非常好的圖片緩存效果,從而使得具備較高的圖片加載效率。
以下是Glide的相關代碼:
3、 緩存類型
活動緩存(ActiveResource):存儲正在使用的圖片;
Lru內存緩存(LruResourceCache):圖片解析完成后并最近被加載過會放到內存中;
磁盤緩存-資源類型(DiskCache - Resource):被解碼后的圖片寫入磁盤文件中;
磁盤緩存-原始數據(DiskCache - Data):網絡請求成功或在本地獲取成功后,將原始數據在磁盤中緩存;
Lru(Least Recently Used):最近最少使用,它的核心思想是,當緩存滿的時候,會優先淘汰最近最少使用的緩存對象。
4、內存緩存/運行時緩存
內存緩存/運行時緩存分為兩部分:活動緩存(ActiveResource)和Lru內存緩存(LruResourceCache)。
LinkedHashMap繼承自HashMap,在此基礎上增加了雙向鏈表的結構,每次訪問數據的時候,會更新被訪問的數據的鏈表指針。比如說從鏈表中刪除并不是真正的刪除數據,只是移動了鏈表的指針。
Lru內存緩存:使用LinkedHashMap來緩存資源(強引用),并設定一個緩存的大小。如果有資源被訪問到,首先會在鏈表中刪除該節點,然后再添加到鏈表頭,這樣就可以保證鏈表頭部的節點是最近訪問過的。而當緩存的數量達最大值的時候,就會將鏈表尾部(最近最少使用)的數據移除。
但是這樣做有一個風險,就是容易將正在使用的資源回收掉。
Glide這樣設計:從內存緩存(LruResourceCache)中拿到資源時候就主動添加到活動緩存(ActiveResource)中,并清理Lru內存緩存(LruResourceCache)中的資源,這樣做的好處就是是保護正在使用資源不被Lru算法回收掉。
ActiveResources是一個弱引用的HashMap,用來緩存正在使用的圖片,保存這個圖片不會被Lru算法回收掉。圖片用完之后會重新添加到Lru內存緩存中。
ActiveResources和LruResourceCache是內存緩存,屬于運行時緩存且互斥(同一張圖片不會同時緩存在ActiveResources和LruResourceCache中),應用被殺死后內存緩存將不存在。
5、 磁盤緩存
磁盤緩存策略:
DiskCacheStrategy.NONE:表示不緩存任何內容;
DiskCacheStrategy.RESOURCE:在資源解碼后將數據寫入磁盤緩存,即經過縮放等轉換后的圖片資源;
DiskCacheStrategy.DATA:在資源解碼前將原始數據寫入磁盤緩存;
DiskCacheStrategy.ALL :使用DATA和RESOURCE緩存數據;
DiskCacheStrategy.AUTOMATIC:它會嘗試對本地和遠程圖片使用最佳的策略。當加載遠程數據時,AUTOMATIC 策略僅會存儲未被加載過程修改過的原始數據,因為下載遠程數據相比調整磁盤上已經存在的數據要昂貴得多。對于本地數據,AUTOMATIC 策略則會僅存儲變換過的縮略圖,因為即使需要再次生成另一個尺寸或類型的圖片,取回原始數據也很容易。默認使用這種緩存策略;
在使用Glide去加載一張圖片的時候,Glide默認不會將原始圖片展示出來,而是會對圖片進行壓縮和轉換。我們既可以緩存轉換過的圖片,也可以緩存轉換之前的原始圖片。
采用LRU算法的緩存有兩種:LruCache和DisLruCache,分別用于實現內粗緩存和硬盤緩存