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