Glide 使用簡明的流式語法API,大多數情況下,可能完成圖片的設置你只需要:Glide.with(activity) .load(url) .into(imageView);
默認情況下,Glide 會在開始一個新的圖片請求之前檢查以下多級的緩存:
1. 活動資源 (Active Resources) 2. 內存緩存 (Memory Cache) 3. 資源類型(Resource Disk Cache) 4. 原始數據 (Data Disk Cache) 活動資源:如果當前對應的圖片資源正在使用,則這個圖片會被Glide放入活動緩存。 內存緩存:如果圖片最近被加載過,並且當前沒有使用這個圖片,則會被放入內存中 資源類型: 被解碼后的圖片寫入磁盤文件中,解碼的過程可能修改了圖片的參數(如:inSampleSize、inPreferredConfig) 原始數據: 圖片原始數據在磁盤中的緩存(從網絡、文件中直接獲得的原始數據)
在調用into之后,Glide會首先從Active Resources查找當前是否有對應的活躍圖片,沒有則查找內存緩存,沒有則查找資源類型,沒有則查找數據來源。

相較於常見的內存+磁盤緩存,Glide將其緩存分成了4層。
第一層 活動資源
當需要加載某張圖片能夠從內存緩存中獲得的時候,在圖片加載時主動將對應圖片從內存緩存中移除,加入到活動資源中。
這樣也可以避免因為達到內存緩存最大值或者系統內存壓力導致的內存緩存清理,從而釋放掉活動資源中的圖片(recycle)。
活動資源中是一個”引用計數"的圖片資源的弱引用集合。
因為同一張圖片可能在多個地方被同時使用,每一次使用都會將引用計數+1,而當引用計數為0時候,則表示這個圖片沒有被使用也就是沒有強引用了。這樣則會將圖片從活動資源中移除,並加入內存緩存。

第二層 內存緩存
內存緩存默認使用LRU(緩存淘汰算法/最近最少使用算法),當資源從活動資源移除的時候,會加入此緩存。使用圖片的時候會主動從此緩存移除,加入活動資源。
LRU在Android support-v4中提供了LruCache工具類。

構造LinkedHashMap的accessOrder設置為true。在使用的此map的時候,自動進行排序(每次get/put,會將使用的value放入鏈表header頭部)。LruCache會在每次get/put的時候判斷數據如果達到了maxSize,則會優先刪除tail尾端的數據。

磁盤緩存同樣使用LRU算法。
第三、四層 磁盤緩存
Resource 緩存的是經過解碼后的圖片,如果再使用就不需要再去進行解碼配置(BitmapFactory.Options),加快獲得圖片速度。比如原圖是一個100x100的ARGB_8888圖片,在首次使用的時候需要的是50x50的RGB_565圖片,那么Resource將50x50 RGB_565緩存下來,再次使用此圖片的時候就可以從 Resource 獲得。不需要去計算inSampleSize(縮放因子)。
Data 緩存的則是圖像原始數據。
Bitmap復用
如果緩存都不存在,那么會從源地址獲得圖片(網絡/文件)。而在解析圖片的時候會需要可以獲得BitmapPool(復用池),達到復用的效果。


復用效果如上。在未使用復用的情況下,每張圖片都需要一塊內存。而使用復用的時候,如果存在能被復用的圖片會重復使用該圖片的內存。
所以復用並不能減少程序正在使用的內存大小。Bitmap復用,解決的是減少頻繁申請內存帶來的性能(抖動、碎片)問題。
https://developer.android.google.cn/topic/performance/graphics/manage-memory.html



Google給出的案例可以看出:
使用方式為在解析的時候設置Options的inBitmap屬性。
- Bitmap的inMutable需要為true。
- Android 4.4及以上只需要被復用的Bitmap的內存必須大於等於需要新獲得Bitmap的內存,則允許復用此Bitmap。
- 4.4以下(3.0以上)則被復用的Bitmap與使用復用的Bitmap必須寬、高相等並且使用復用的Bitmap解碼時設置的inSampleSize為1,才允許復用。
因此Glide中,在每次解析一張圖片為Bitmap的時候(磁盤緩存、網絡/文件)會從其BitmapPool中查找一個可被復用的Bitmap。
BitmapPool是Glide中的Bitmap復用池,同樣適用LRU來進行管理。
當一個Bitmap從內存緩存 被動 的被移除(內存緊張、達到maxSize)的時候並不會被recycle。而是加入這個BitmapPool,只有從這個BitmapPool 被動
被移除的時候,Bitmap的內存才會真正被recycle釋放。
原創文章,轉載請聯系作者哦~~
微信公眾號:終端研發部
