Glide Module 案例: 自定義緩存
原文:Glide Module Example: Customize Caching
作者:Norman Peitek
翻譯:Dexter0218
在上篇文章中,我們學習了使用一個定制的HTTP client接收self-signed HTTPS證書設置到Glide module里的過程。本文,停留在一個低水平,看一下定制Glide緩存部分的案例。
Glide 系列概覽
- 入門簡介
- 高級加載
- 適配器(ListView, GridView)
- 占位圖& 淡入淡出動畫
- 圖片大小 & 縮放
- 播放GIF & 視頻
- 緩存基礎
- 請求優先級
- 縮略圖
- 回調:定制view中使用SimpleTarget和ViewTarget
- 通知欄和桌面小控件的圖片加載
- 異常: 調試和報錯處理
- 自定義變換
- 用animate()定制動畫
- 整合網絡協議棧
- 用Modules定制Glide
- Glide Module 案例: 接受自簽名HTTPS證書
- Glide Module 案例: 自定義緩存
- Glide Module 案例: 通過加載自定義大小圖片優化
- 動態使用 Model Loaders
- 如何旋轉圖片
- 系列綜述
自定義內存緩存 ##
希望你已經讀過緩存的基礎知識和Glide module的文章。否則下面的代碼可能看不懂。如果你準備好了,那就開始看吧。
既然我們自定義Glide,我們需要創建一個Glide module。在前面的文章中介紹過,applyOptions
方法提供了訪問GlideBuilder
對象的方法。GlideBuilder
方法提供了幾個方法去自定義Glide的緩存。首先,看看內存緩存。
內存緩存是在設備的RAM中保存圖片。由于沒有IO操作,所以非常快。不利的是由于RAM的大小是收到限制的。在小內存緩存和大內存緩存之間找到一個合適的平衡點并不簡單。Glide內存使用MemorySizeCalculator
類去決定內存緩存和bitmap池的大小。Bitmap池保存著在你的應用heap里放著的圖片。Bitmap池的正確大小是很重要的,防止太多重新分配圖片,這樣可以讓垃圾回收器的生命更簡單。
幸運地,你已經接觸到Glide的MemorySizeCalculator
類和默認的計算:
MemorySizeCalculator calculator = new MemorySizeCalculator(context);
int defaultMemoryCacheSize = calculator.getMemoryCacheSize();
int defaultBitmapPoolSize = calculator.getBitmapPoolSize();
如果你想要使用默認值作為基線并調整,上面的代碼是非常有用的。例如,如果你想要你的app比默認多20%的緩存,使用上面的變量來計算它們:
int customMemoryCacheSize = (int) (1.2 * defaultMemoryCacheSize);
int customBitmapPoolSize = (int) (1.2 * defaultBitmapPoolSize);
由于我們已經指出我們的內存緩存和Bitmap池的大小,我們可以最終可以編碼我們的Glide module。在applyOption()
方法,我們可以在GlideBuilder
對象上調用合適的方法:
public class CustomCachingGlideModule implements GlideModule {
@Override public void applyOptions(Context context, GlideBuilder builder) {
MemorySizeCalculator calculator = new MemorySizeCalculator(context);
int defaultMemoryCacheSize = calculator.getMemoryCacheSize();
int defaultBitmapPoolSize = calculator.getBitmapPoolSize();
int customMemoryCacheSize = (int) (1.2 * defaultMemoryCacheSize);
int customBitmapPoolSize = (int) (1.2 * defaultBitmapPoolSize);
builder.setMemoryCache( new LruResourceCache( customMemoryCacheSize );
builder.setBitmapPool( new LruBitmapPool( customBitmapPoolSize );
}
@Override public void registerComponents(Context context, Glide glide) {
// nothing to do here
}
}
在applyOptions()
方法的最后兩行可以看出,我們不能直接設置大小。我們創建一個LruResourceCache
和LruBitmapPool
類的實例。這個兩個都是Glide的默認實現。這樣,如果你想要調整大小,你可以只通過傳遞一個不同大小的值到構造器繼續使用它們。
自定義磁盤緩存
調整磁盤緩存的工作也類似,只是我們需要多做一個決定。磁盤緩存可以存在app的私有目錄下(換句話說,除非你自己的app,其它app訪問不了)。不然,磁盤緩存可以存在外部,公共路徑(更多信息,請看存儲方案)。默認設置下兩個存儲的結合是不可能的。Glide提供了另一個用InternalCacheDiskCacheFactory
和ExternalCacheDiskCacheFactory
的方案。就像內存緩存的構造器,磁盤緩存工廠在它們的構造器里接收一個大小的值:
public class CustomCachingGlideModule implements GlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
// set size & external vs. internal
int cacheSize100MegaBytes = 104857600;
builder.setDiskCache(
new InternalCacheDiskCacheFactory(context, cacheSize100MegaBytes)
);
//builder.setDiskCache(
//new ExternalCacheDiskCacheFactory(context, cacheSize100MegaBytes));
}
@Override
public void registerComponents(Context context, Glide glide) {
// nothing to do here
}
}
上面的代碼會設置磁盤緩存到app的內部路徑,并設置最大值到100M。注釋斜線后面的那行,會設置磁盤緩存到外部路徑(并設置最大值到100M)。
上面的兩個方案都不讓你選擇一個特定的路徑。如果你需要移動磁盤緩存到某個特定的位置,你可以利用DiskLruCacheFactory
:
// or any other path
String downloadDirectoryPath = Environment.getDownloadCacheDirectory().getPath();
builder.setDiskCache(
new DiskLruCacheFactory( downloadDirectoryPath, cacheSize100MegaBytes )
);
// In case you want to specify a cache sub folder (i.e. "glidecache"):
//builder.setDiskCache(
// new DiskLruCacheFactory( downloadDirectoryPath, "glidecache", cacheSize100MegaBytes )
//);
使用上面的方案去直接設置一個路徑。底部的注釋的代碼會創建并使用一個在你傳遞路徑里的路徑。通常,最后一個參數是byte級緩存的大小。
自定義緩存實現
到目前為止,我們已經展示了如何移動,設置緩存大小。然而,所有調用指向緩存的原始實現。如果你有自己的緩存實現呢?
好吧,你已經知道我們總是創建一個Glide的默認緩存實現實例。你可以創建它的實例并在上面看到的所有方法里傳遞它來完成你自己的實現。你只要確保你的緩存代碼實現了接口方法:
- Memory cache needs to implement: MemoryCache
- Bitmap pool needs to implement BitmapPool
- Disk cache needs to implement: DiskCache
展望
本文中,介紹了如何改變和自定義Glide的緩存。Glide的默認實現組織很好,所以確保你有改變它的原因。如果你要改變一些東西,確保在一定范圍的設備上測試!
后面,我們將學習另一個Glide module主題。下篇文章將介紹在大小確定的target ImageView里如何實現一個圖片請求,我們保證,將會很棒!