在上篇博客,我們用一個自定義的 HTTP 客戶端設置了自己的 Glide module,它接受一個自簽名的 HTTPS 證書。這周,我們仍然停留在低水平上去定制一個 Glide 組件的緩存。
**自定義內存緩存**?
希望你已經讀了 [caching basics](https://futurestud.io/blog/glide-caching-basics) 和 [Glide modules](https://futurestud.io/blog/glide-customize-glide-with-modules) 博客。否則,看下面的代碼對你來說可能像魔術一般了。如果你讀過了,那就繼續讀下去。
好吧,既然是定制 Glide,我們就需要創建一個新的 Glide module。就如你在以前博客中看到的那樣,`applyOptions` 方法使我們獲取了 `GlideBuilder` 對象。該 `GlideBuilder` 為我們提供了幾個方法去定制 Glide 的緩存。首先,來看看內存緩存。
內存緩存是在設備的 RAM 中去維護圖片的。這里沒有 IO 行為,所以這個操作是很快的。另一方面是 RAM(內存) 的大小是非常有限的。尋找一個大內存緩存的平衡點(大量圖像空間)與一個小內存緩存(最大限度減少我們 App 的資源消耗)并不容易。Glide 內部使用了 [MemorySizeCalculator](http://bumptech.github.io/glide/javadocs/latest/com/bumptech/glide/load/engine/cache/MemorySizeCalculator.html) 類去決定內存緩存大小以及 bitmap 的緩存池。bitmap 池維護了你 App 的堆中的圖像分配。正確的 bitmpa 池是非常必要的,因為它避免很多的圖像重復回收,這樣可以確保垃圾回收器的管理更加合理。
幸運的是,你已經得到了 Glide 的 `MemorySizeCalculator` 類以及默認的計算:
~~~
MemorySizeCalculator calculator = new MemorySizeCalculator(context);
int defaultMemoryCacheSize = calculator.getMemoryCacheSize();
int defaultBitmapPoolSize = calculator.getBitmapPoolSize();
~~~
上面這段代碼相當有用,如果我們想要用默認值作為基準,然后調整它。比如,如果你認為你的 app 需要 20% 大的緩存作為 Glide 的默認值,用我們上面的變量去計算他們:
~~~
int customMemoryCacheSize = (int) (1.2 * defaultMemoryCacheSize);
int customBitmapPoolSize = (int) (1.2 * defaultBitmapPoolSize);
~~~
因為我們已經計算出了我們的內存緩存和 bitmap 池的大小,我們可以在我們的 Glide module 代碼里去得到。在 `applyOptions()` 方法中,我們可以在 `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 的默認實現。因此,如果你僅僅想要調整大小,就可以繼續使用它們通過傳兩個不同的大小的值給構造函數。
**自定義磁盤緩存?**
調整磁盤緩存和和剛才的很像,但是我們有一個更大的決定去做,磁盤緩存可以位于應用的私有目錄(換句話說,除了它自己,沒有別的應用可以訪問)。否則,磁盤緩存也可以位于外部存儲,公有目錄(更多信息,請看 [Storage Options](https://developer.android.com/guide/topics/data/data-storage.html?hl=zh-cn))。不能一起設置這兩個為之。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
}
}
~~~
上面的代碼將設置磁盤緩存到應用的內部目錄,并且設置了最大的大小為 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 )
//);
~~~
**自定義緩存實現**?
目前為止,我們已經向你展示了如何去移動和設置緩存為確定的大小。然而,所有的調用都引用了緩存的原始實現。如果你有你自己的緩存實現呢?
嗯,你看到我們總是創建一個 Glide 的默認緩存的實現的新實例。你可以完成你自己的實現,創建和實例化它,并用上上面所有你看到的方法。你必須確保你的緩存代碼實現了如下接口方法:
* Memory cache needs to implement: [MemoryCache](http://bumptech.github.io/glide/javadocs/latest/com/bumptech/glide/load/engine/cache/MemoryCache.html)
* Bitmap pool needs to implement [BitmapPool](http://bumptech.github.io/glide/javadocs/latest/com/bumptech/glide/load/engine/bitmap_recycle/BitmapPool.html)
* Disk cache needs to implement: [DiskCache](http://bumptech.github.io/glide/javadocs/latest/com/bumptech/glide/load/engine/cache/DiskCache.html)
**Outlook?**
在這篇博客中,你已經看到了如何改變和定制 Glide 的緩存,Glide 的默認實現已經是全面的了,所以確保你有足夠的理由而去改變這些事情。如果你做了一些改變,確保設備的覆蓋測試。
下周,我們會看到另一個 Glide module 話題。我們會看到如何去實現一個組件,它要求圖片在目標 ImageView 有精確的大小。我們保證,這很棒!
- 前言
- 一開始
- 二加載進階
- 三ListAdapter(ListView, GridView)
- 四占位符 和 漸現動畫
- 五圖片重設大小 和 縮放
- 六顯示 Gif 和 Video
- 七緩存基礎
- 八請求優先級
- 九縮略圖
- 十回調:SimpleTarget 和 ViewTarget 用于自定義視圖類
- 十一加載圖片到通知欄和應用小部件中
- 十二異常:調試和錯誤處理
- 十三自定義轉換
- 十四用 animate() 自定義動畫
- 十五集成網絡棧
- 十六用 Module 自定義
- 十七Module 實例:接受自簽名證書的 HTTPS
- 十八Module 實例:自定義緩存
- 十九Module 實例:用自定義尺寸優化加載的圖片
- 二十動態使用 Model Loader
- 二十一如何旋轉圖像
- 二十二系列綜述