默認(rèn)情況下,Glide會在請求圖像之前檢查多級緩存:
前兩個步驟是檢查資源是否在內(nèi)存中。如果是, 立即返回該圖像。后兩個步驟是檢查該圖像是否在磁盤中,如果是也很快返回,不過是異步的。
如果所有四個步驟都沒有找到圖像,Glide會返回原始資源去檢索數(shù)據(jù)(原始文件,URI,URL等)。
在Glide 4中,所有的緩存鍵至少包含兩個元素:
實際上,步驟1-3的緩存鍵(活躍資源,內(nèi)存緩存,磁盤資源緩存)還包括許多其他數(shù)據(jù),其中包括:
用于活躍資源和內(nèi)存緩存中鍵跟緩存在磁盤中的鍵有些微不同,像那些影響B(tài)itmap的配置或解碼時間參數(shù)的選項。
為了生成磁盤緩存鍵的名字,各個元素生成唯一的散列字符串,然后作為磁盤緩存的文件名。
Glide提供了一些選項,允許您選擇在Glide的每次基礎(chǔ)請求時怎么跟負(fù)載交互。
使用DiskCacheStrategy方法可以為每個請求應(yīng)用磁盤緩存策略,可用的策略可以防止負(fù)載使用或者寫入磁盤高速緩存或者選擇那些負(fù)載返回的未修改原始數(shù)據(jù)來緩存,或者轉(zhuǎn)換您的負(fù)載產(chǎn)生的縮略圖,或者兩者都具備。
默認(rèn)策略是自動匹配,嘗試為本地或者遠(yuǎn)程圖像使用最優(yōu)策略。當(dāng)您加載遠(yuǎn)程數(shù)據(jù)(如從URL加載)時,自動匹配只會保存負(fù)載返回的未修改的原始數(shù)據(jù),因為相比調(diào)整磁盤數(shù)據(jù)的尺寸,下載遠(yuǎn)程數(shù)據(jù)更加昂貴。對于本地資源,自動匹配只會存儲轉(zhuǎn)換縮略圖,因為如果您需要生成縮略圖尺寸或者類型,檢索原始數(shù)據(jù)花費更少。
應(yīng)用磁盤緩存策略的例子:
GlideApp.with(fragment)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(imageView);
在一些情況下,如果圖像不在緩存中,您可能希望加載失敗。因此,您可以在每個基礎(chǔ)負(fù)載中使用onlyRetrieveFromCache方法:
GlideApp.with(fragment)
.load(url)
.onlyRetrieveFromCache(true)
.into(imageView);
如果圖像可以在內(nèi)存緩存或者磁盤緩存中找到,那么它會被成功加載。否則,如果選項設(shè)置成true,加載會失敗。
如果您希望確保特定的請求跳過磁盤緩存跟內(nèi)存緩存,Glide提供了一些替代選擇。只是跳過內(nèi)存緩存,可以使用skipMemoryCache:
GlideApp.with(fragment)
.load(url)
.skipMemoryCache(true)
.into(view);
只是跳過磁盤緩存,使用DiskCacheStrategy.NONE:
GlideApp.with(fragment)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.into(view);
這些選項可以一起使用:
GlideApp.with(fragment)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(view);
一般來說,您要盡量避免跳過緩存。從緩存中加載圖像要比檢索,解碼,轉(zhuǎn)換并創(chuàng)建一個新的縮略圖快得多。
如果您想為緩存中的某一項更新條目,您可以查看文檔invalidation
如果可用的選項不滿足您的需求,您可以自定義您的DiskCache實現(xiàn)。查看configuration獲取細(xì)節(jié)。
由于磁盤緩存是散列鍵,所以也沒有好的辦法簡單的刪除在磁盤上的所有的對應(yīng)特定的URL或者文件路徑的緩存文件。比較簡單的方式是如果您只允許加載或者緩存原始圖像,但只要Glide緩存縮略圖并且提供各種轉(zhuǎn)換,它們每個都將在磁盤中生成新的文件,跟蹤下載并且刪除每個版本的緩存圖像是困難的。
通常很難或者不可能改變標(biāo)識符,所以Glide提供了signature() API和額外的數(shù)據(jù),使您可以控制緩存鍵。簽名適用于媒體存儲內(nèi)容,以及任何您可以維護(hù)版本的元數(shù)據(jù)。
將簽名傳遞給負(fù)載的例子:
GlideApp.with(yourFragment)
.load(yourFileDataModel)
.signature(new ObjectKey(yourVersionMetadata))
.into(yourImageView);
媒體存儲簽名也是媒體存儲的簡單數(shù)據(jù):
GlideApp.with(fragment)
.load(mediaStoreUri)
.signature(new MediaStoreSignature(mimeType, dateModified, orientation))
.into(view);
您可以實現(xiàn)Key接口來定義自己的簽名。確保實現(xiàn)了equals(),hashCode()和updateDiskCacheKey方法。
public class IntegerVersionSignature implements Key {
private int currentVersion;
public IntegerVersionSignature(int currentVersion) {
this.currentVersion = currentVersion;
}
@Override
public boolean equals(Object o) {
if (o instanceof IntegerVersionSignature) {
IntegerVersionSignature other = (IntegerVersionSignature) o;
return currentVersion = other.currentVersion;
}
return false;
}
@Override
public int hashCode() {
return currentVersion;
}
@Override
public void updateDiskCacheKey(MessageDigest md) {
messageDigest.update(ByteBuffer.allocate(Integer.SIZE).putInt(signature).array());
}
}
請記住,為了避免降低性能,您需要在后臺批量加載任何版本的元數(shù)據(jù),以便在加載圖像時可用。
如果一切都失敗了,您不能改變標(biāo)識符也不能跟蹤任何版本的元數(shù)據(jù),您可以使用diskCacheStrategy()和DiskCacheStrategy.NONE關(guān)閉磁盤緩存。