磁盤緩存、內存緩存與BitmapPool都是使用LRU算法,Glide維護每個緩存的引用計數,當緩存將超過容量限制時,引用計數最少的緩存被釋放。
磁盤緩存(Disk Cache)
- 默認配置
1、存儲位置:內部存儲
2、最大LRU磁盤緩存容量:250MB(DEFAULT_DISK_CACHE_SIZE)
3、路徑名:“image_manager_disk_cache”(DEFAULT_DISK_CACHE_DIR) - 修改配置
//內部存儲
builder.setDiskCache(
new InternalCacheDiskCacheFactory(context, cacheDirectoryName, yourSizeInBytes));
//外部存儲
builder.setDiskCache(
new ExternalCacheDiskCacheFactory(context, cacheDirectoryName, yourSizeInBytes));
//InternalCacheDiskCacheFactory爲內部存儲,ExternalCacheDiskCacheFactory爲外部存儲
//cacheDirectoryName:配置路徑名
//yourSizeInBytes:配置最大容量
- 修改磁盤緩存策略
v3
緩存策略 | 描述 |
---|---|
ALL | 同時保存未修改的原始圖片與修改後的圖片 |
NONE | 取消磁盤緩存 |
SOURCE | 僅保存未修改的原始圖片 |
RESULT(默認) | 僅保存修改後的圖片 |
Glide.with(fragment)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(imageView);
v4
緩存策略 | 描述 |
---|---|
ALL | 對於遠程圖片,同時保存未修改的原始圖片和修改後的圖片;對於本地圖片,僅保存修改後的圖片 |
NONE | 取消磁盤緩存 |
DATA | 僅保存未修改的原始圖片 |
RESOURCE | 僅保存修改後的圖片 |
AUTOMATIC(默認) | 默認情況與ALL相同 |
GlideApp.with(fragment)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(imageView);
- 清理磁盤緩存(在後臺線程)
Glide.get(applicationContext).clearDiskCache();
- 僅從磁盤或內存緩存中獲取(v4有效)
GlideApp.with(this)
.load("")
.onlyRetrieveFromCache(true)
.into(imageView)
內存中緩存
- 系統劃分給進程的可用內存容量:基於硬件不同,取值爲16MB、24MB或者更高。
- Glide從可用內存容量中取一部分作爲最大內存佔用量:
v3
設備 | 最大內存佔用量 |
---|---|
低內存設備 | 可用內存容量*0.33F |
非低內存設備 | 可用內存容量*0.4F |
v4
設備 | 默認最大內存佔用量 | 可自定義最大內存佔用量 |
---|---|---|
低內存設備 | 可用內存容量*0.33F | 可用內存容量*比例 |
非低內存設備 | 可用內存容量*0.4F | 可用內存容量*比例 |
- 最大內存佔用量分配給內存緩存與位圖池緩存
顯示一個屏幕所有像素需要的內存爲screenSize。
v3
未超過最大內存佔用量 | 超過最大內存佔用量 | |
---|---|---|
Memory Cache | screenSize*2屏 | 最大內存佔用量*2/6 |
BitmapPool | screenSize*4屏 | 最大內存佔用量*4/6 |
v4
Android O之前
未超過最大內存佔用量 | 超過最大內存佔用量 | |
---|---|---|
Memory Cache | screenSize*2屏 | 最大內存佔用量*2/6 |
BitmapPool | screenSize*4屏 | 最大內存佔用量*4/6 |
Android O之後
未超過最大內存佔用量 | 超過最大內存佔用量 | |
---|---|---|
Memory Cache | screenSize*2屏 | 最大內存佔用量*2/3 |
BitmapPool | screenSize*1屏 | 最大內存佔用量*1/3 |
v4可用自定義屏幕數
- 動態調整容量
Glide.get(context).setMemoryCategory(MemoryCategory);
MemoryCategory | 描述 |
---|---|
LOW | 使用初始容量的一半 |
NORMAL | 使用初始容量 |
HIGH | 使用初始容量的1.5倍 |
內存緩存(Memory Cache)
- 配置初始容量
v3
builder.setMemoryCache(new LruResourceCache(customMemoryCacheSize );
v4
builder.setMemoryCache(new LruResourceCache(customMemoryCacheSize );
或
MemorySizeCalculator.Builder builder= new MemorySizeCalculator.Builder(context);
builder.setMemoryCacheScreens(int);//內存緩存的屏數
builder.setBitmapPoolScreens(int);//BitmapPool的屏數
builder.setMaxSizeMultiplier(float);//從進程可用內存劃分的比例
builder.setLowMemoryMaxSizeMultipiler(float);//低內存設備時從進程可用內存劃分的比例
builder.setMemoryCache(builder.build().getMemoryCacheSize());
- 取消內存緩存
v3
Glide.with(fragment)
.load(url)
.skipMemoryCache(false)
.into(imageView);
v4
GlideApp.with(fragment)
.load(url)
.skipMemoryCache(false)
.into(imageView);
- 清理內存緩存(在主線程)
Glide.get(applicationContext).clearMemory();
位圖池緩存(BitmapPool)
- 配置初始容量
v3
builder.setBitmapPool(new LruBitmapPool(customBitmapPoolSize ));
v4
builder.setBitmapPool(new LruBitmapPool(customBitmapPoolSize ));
或
MemorySizeCalculator.Builder builder= new MemorySizeCalculator.Builder(context);
builder.setMemoryCacheScreens(int);//內存緩存的屏數
builder.setBitmapPoolScreens(int);//BitmapPool的屏數
builder.setMaxSizeMultiplier(float);//從進程可用內存劃分的比例
builder.setLowMemoryMaxSizeMultipiler(float);//低內存設備時從進程可用內存劃分的比例
builder.setMemoryCache(builder.build().getBitmapPoolSize());
緩存刷新問題
因爲磁盤緩存使用的是哈希鍵,所以並沒有一個比較好的方式來簡單地刪除某個特定url或文件路徑對應的所有緩存文件。如果你只允許加載或緩存原始圖片的話,問題可能會變得更簡單,但因爲Glide還會緩存縮略圖和提供多種變換(transformation),它們中的任何一個都會導致在緩存中創建一個新的文件,而要跟蹤和刪除一個圖片的所有版本無疑是困難的。
使用簽名插入到哈希鍵中來控制緩存刷新。
GlideApp.with(fragment)
.load(mediaStoreUri)
.signature(new MediaStoreSignature(mimeType, dateModified, orientation))
.into(view);
MediaStoreSignature(String mimeType, long dateModified, int orientation)
StringSignature(String signature)
v4
ObjectKey(Object object)
v3和v4的配置API差異
v3
v3使用GlideModule接口實現懶配置,步驟:
- 1、實現GlideModule接口,在applyOptions(…)方法中應用配置選項(如緩存配置選項),在registerComponents(…)方法中註冊ModelLoaders;
- 2、添加對GlideModule接口的混淆忽略;
- 3、在AndroidManifest.xml中的<application>下添加meta-data,name屬性值爲類名,value屬性值固定爲“GlideModule”。
所謂懶配置,即直到應用首次發起Glide請求,纔會自動地進行配置。Glide先遍歷AndroidManifest.xml中<application>下所有的<meta-data>,匹配value爲“GlideModule”的meta-data。再利用其中的name屬性,通過反射機制得到該GlideModule子類的實例。(源碼:ManifestParser類)
v4
v4使用編譯時註解避免運行時遍歷meta-data的過程。
v3使用一個或多個GlideModule完成配置,v4使用有且只有一個AppGlideModule加可選的多個LibraryGlideModule完成配置。
v4的註解編譯器在編譯時彙總AppGlideModule類和LibraryGlideModule類中的配置邏輯,生成類名爲GeneratedAppGlideModuleImpl的配置類。在運行時懶配置觸發時,Glide反射這個自動生成的類,完成配置。
步驟:
- 1、實現AppGlideModule接口,在applyOptions(…)方法中應用配置選項(如緩存配置選項),在registerComponents(…)方法中註冊ModelLoaders;
- 2、可選地實現LibraryGlideModule接口,在registerComponents(…)方法中註冊ModelLoaders;
- 3、實現AppGlideModule和LibraryGlideModule接口時需要添加@GlideModule註解
- 4、添加混淆忽略
v4關閉解析AndroidManifest.xml的步驟:重寫AppGlideModule#isManifestParsingEnabled(),返回false。