當前位置:首頁 » 硬碟大全 » glide緩存圖片命名規則
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

glide緩存圖片命名規則

發布時間: 2023-05-06 10:03:53

A. Glide圖片載入的用法介紹和三級緩存實現

Glide庫是用來實現圖片載入的框架,功能強大且易使用,深受大家喜愛。

為啥要做緩存? android默認給每個應用只分配16M的內存,所以如果載入過多的圖片,為了 防止內存溢出 ,應該將圖片緩存起來。

圖片的三級緩存分別是:

1、內存緩存
2、本地緩存
3、網路緩存
其中,內存緩存應優先載入,它速度最快;本地緩存次優先載入,它速度也快;網路緩存不應該優先載入,它走網路,速度慢且耗流量。

最優-優先順序:內存緩存 > 本地緩存 > 網路緩存

兩個方法實現:根據圖片的url去載入圖片、在本地和內存中緩存

兩個方法實現:設置本地緩存,以及獲取本地緩存

兩個方法實現:設置內存緩存,獲取內存緩存。

如果使用hashmap去存儲圖片時,當圖片越來越多,那麼會造成內存溢出,因為是強引用(對於強引用的系統不會回收)

如果改成軟引用softReference,在android 2.3 以上的系統,對象會被提前回收。

可以用LruCache來解決上述內存不回收或提前回收的問題。least recentlly use 最少最近使用演算法 它會將內存控制在一定的大小內, 超出最大值時會自動回收, 這個最大值開發者自己定。(這個東西沒有用過..)

參考鏈接: https://blog.csdn.net/sinat_20645961/article/details/46325243

B. Glide ② — 緩存機制

閱讀本文需要先了解 Glide載入流程

首先介紹一下Glide中對圖片資源的封裝類: EngineResource

在活動緩存中,使用了一個map用來存放EngineResource對象,這里需要注意一個操作,就是這個EngineResource對象是用WeakReference包裹的,並且通過ReferenceQueue監聽了EngineResource的回收,在回收的時候會清理當前的活動緩存內容;
下面分析一下源碼是如果實現的:
首先,自定義一個WeakReference類,將key和resource傳進入(用於在WeakReference回收的時候釋放),傳入一個ReferenceQueue對象,用於監聽WeakReference回收

開啟一個子線程,在循環中監聽ReferenceQueue的返回值,通過這個返回值,判斷WeakReference有沒有回收,監聽的方法是ReferenceQueue.remove(),這是一個阻塞方法;所以要開子線程;

LruResourceCache繼承了LruCache類,關於LruCache類,簡單提一下,具體的可以參考我之前的博客 LruCache實現 ,LruCache繼承了LinkedHashMap,LinkedHashMap有一個特點,就get後的數據會移動到隊列,這就是Lru思想:固定一個容量,put的時候如果超過容量了,將最後一個節點刪除,get的時候將get的這個節點移動到隊列的頭部;

onItemEvicted()方法是LruCache的一個空方法,調用的時機是在put的時候判斷是否超過容量,如果超過容量了,就淘汰最後一個節點,並調用這個方法;

活動緩存和內存緩存都是緩存在內存中的,活動緩存緩存的是正在使用的圖片資源,當圖片不使用時會放到內存緩存中,提出活動緩存的目的:單一的內存緩存由於Lru的淘汰機制會導致圖片載入不穩定

首先介紹一個磁碟緩存方案DiskLruCache(非Google官方編寫,但獲得官方認證),關於這個磁碟緩存方案的理解可以看郭林的這片文章:
Android DiskLruCache完全解析,硬碟緩存的最佳方案

從上一篇文章知道,Glide載入操作是通過 Engine 來驅動的

Engine的load()中,首先嘗試從 活動緩存 和 內存緩存 獲取緩存,如果沒有緩存再啟動EngineJob和DecodeJob; 上面介紹了緩存的獲取,下面看一下緩存的存放,肯定是在獲取到圖片後的回調中存放的

在DecodeJob獲取到圖片數據後,會回調很多介面,在回調中會將其放入 活動緩存 ,當圖片不在使用的時候,就會放入內存緩存,根據上面介紹的活動緩存規則,當 EngineResource 計數為0時就應該放入內存緩存;

當資源引用為0,回調onResourceReleased(),從活動緩存移除,放入內存緩存;

上面介紹了活動緩存和內存緩存的存放和獲取,下面看一看磁碟緩存的存取;

還記得 DataFetcherGenerator 介面嗎?這個介面是DecodeJob用於獲取數據的,有三個具體的實現:

我們在上一篇具體介紹的是網路文件的獲取,這里的磁碟緩存使用的就是 DataCacheGenerator(緩存文件) 這個Generator了

上篇文章知道DecodeJob是一個Runnable任務,在run()會調用runWrapped(),在runWrapped()中會做三種事情:

在runWrapped()的解碼操作中會執行decode(),在decode()中,會disk put操作;

Glide的磁碟緩存是基於DiskLruCache 實現的,Glide直接使用的是DiskLruCacheWrapper對象對DiskLruCache 的封裝;

C. glidecache是什麼文件夾

glidecache是圖片緩存的文件夾,該文件夾可以刪除,但是刪除的同時會刪除手機中的緩存圖片,通過刪除此文件夾刪除的緩存圖片無法找回,一旦刪除無法恢復。

手機緩存是數據交換的緩沖區,緩存是CPU的一部分,它存在於CPU中,而CPU存取數據的速度則非常的快,一秒鍾能夠存取,處理十億條指令和數據。

而內存就慢很多,緩存是為了解決CPU速度和內存速度的速度差異問題,在打開文件時,系統會將數據從內存中復制到一個緩沖區而再打開文件時,系統會直接讀取緩存中的數據,則不用到內存中讀取, 這樣瀏覽文件的速度會比較快。

D. Glide 圖片庫原理(三)緩存機制

查找緩存使用

用完移除

源碼中查看EngineKey-----相當於key,演算法序列abcdsxxfaskldfjklf...
源碼中查看Source-----相當於value(Bitmap),調用系統轉換成Bitmap

情景: 相冊類的App經常需要同時展示大量的圖片,這種情況下圖片的質量可以低一點,因為載入速度優先於圖片的質量。

解決辦法: 我們可以設置解碼的格式,在RequestOptions中加入.encodeFormat(Bitmap.CompressFormat.WEBP).encodeQuality(10))的選項,①encodeFormat的參數有Bitmap.CompressFormat.PNG,Bitmap.CompressFormat.JPEG,Bitmap.CompressFormat.WEBP(質量從高到低);②encodeQuality設置的是0-100的int類型,一個質量百分比參數,越小質量越低。

情景: 大體的意思應該是同一個URL在不同的時間可能會指向不同的資源,所以同樣需要實時更新。

解決辦法相同

情景: 開發一款有頭像的APP,我們修改了頭像並且更新到了服務端,可是當我們點擊查看大圖時載入出來的還是原來的頭像。

解決辦法: 這是Glide強大的緩存帶來的副作用,我們可以在RequestOptions中加入.diskCacheStrategy(DiskCacheStrategy.NONE).skipMemoryCache(true)的選項。那麼緩存的功能就會全部關閉,從而使得每次都是從服務端載入,所以頭像會是最新。

情景: 省流量模式的應用情景就是減少不必要圖片的載入。

解決辦法: 我們可以在RequestOptions中加入onlyRetrieveFromCache(true)的選項。那麼圖片就只會從緩存中讀取,如果沒有緩存則不載入圖片,從而達到減少流量消耗的目的。

E. Android-Glide的緩存機制

很多小夥伴都在使用 Glide 載入圖片,出去面試的時候肯定會被問蔽備起,「Glide緩存機制,你了解多少?」。這篇博客我來說說我了解到的 Glide 的緩存機制。

默認情況下,Glide 會在開始一個新的圖片請求之前檢查以下多級的緩存:
1.活動資源 (Active Resources) - 現在是否有另一個 View 正在展示這張圖片?
2.內存緩存 (Memory cache) - 該圖片是否最近被載入過並仍存在於內存中?
3.資源類型(Resource) - 該圖片是否之前曾被解碼緩讓、轉換擾並局並寫入過磁碟緩存?
4.數據來源 (Data) - 構建這個圖片的資源是否之前曾被寫入過文件緩存?

設置內存緩存開關:

設置磁碟緩存模式:

可以設置4種模式:

F. Glide獲取圖片緩存文件名Key

最近項目由於需要支持gif動圖,所以把圖片載入框架由 ImageLoader 切換到 glide ,因為需要支持長按保存圖片,所以就需要找到 glide 加橋搭帆載後緩存的圖片路徑。
根據網上資料,最終找到 Glide 最終生成path的路徑為: /data/枝沒data/your_packagexxxxxxx/cache/image_manager_disk_cache
對應的生成規則: com.bumptech.glide.load.engine.EngineKey#updateDiskCacheKey
問題轉換為:獲取url到緩存文件path的生成規則演算法上
直接把獲取函數貼出敏雹來:

G. Glide圖片緩存策略

Glide四級緩存:

先找內存,再找文件

1)活動緩存(活動資源):ActiveResource,里邊使用一個弱衫悶引用weakHashMap來保存正在使用的圖片,當我們載入圖殲襪片的時候,先從activeResource里邊去查找,如果找不到的話就從內存緩存里查找。理論上沒有大小限制,但是因為是弱引用管理的,所以是可回收的。 存活於內存當中,非持久化

2)內存緩存:默認使用的是LRU的memoryCache,如果沒有找到,將從文件緩存中查找。 存活於內存當中,非持久化。

3)文件緩存:先從資源類型文件里查找(經過了圓角縮放處理的),然後從數據來源文件(未經過處理)里查找, 存活於磁碟中,持久化

這種框架的基本思路:源碼的三條主線

(1)請求是怎樣發送的?

(2)請求是怎樣處理的?

(3)或改彎請求是怎樣維護的?

Glide.with(context)  ---->構建一個RequestManager

.load()  ------------->輸入數據模型,創建一個RequestBuilder,建造者模式

.into()------->調用RequestBuilder的load方法,buildRequest方法,傳入target,