android glide的历史,Android 图片加载的那些事:为什么你的Glide 缓存没有起作用?...
前言Glide,該功能非常強(qiáng)大 Android ?圖片加載開源框架 相信大家并不陌生
正由于他的功能強(qiáng)大,所以它的源碼非常復(fù)雜,這導(dǎo)致很多人望而卻步
本人嘗試將 Glide 的功能進(jìn)行分解,并單獨針對每個功能進(jìn)行源碼分析,從而降低Glide源碼的復(fù)雜度。接下來,我將推出一系列關(guān)于 Glide的功能源碼分析,有興趣可以繼續(xù)關(guān)注
今天,我將主要講解在使用Glide緩存功能時的問題:為什么Glide 的緩存無起作用,希望你們會喜歡。
1. 背景Glide實現(xiàn)內(nèi)存 & 磁盤緩存是根據(jù) 圖片的緩存Key進(jìn)行唯一標(biāo)識
開發(fā)者為了降低成本 & 安全,往往會將圖片存放在云服務(wù)器上如 七牛云 等等。
為了保護(hù) 客戶的圖片資源,圖片云服務(wù)器 會在圖片Url地址的基礎(chǔ)上再加一個token參數(shù)http://url.com/image.jpg?token=a6cvva6b02c670b0aGlide加載該圖片時,會使用加了token參數(shù)的圖片Url地址 作為
id參數(shù),從而生成 緩存Key
2. 問題作為身份認(rèn)證的token參數(shù)可能會發(fā)生變化,并不是一成不變
若 token參數(shù)變了,則圖片Url跟著變,則生成緩存key的所需id參數(shù)發(fā)生變化,即 緩存Key也會跟著變化
這導(dǎo)致同一張圖片,但因為token參數(shù)變化,而導(dǎo)致緩存Key發(fā)生變化,從而使得 Glide的緩存功能失效緩存Key發(fā)生變化,即同一個圖片的當(dāng)前緩存key 和 之前寫入緩存的key不相同,這意味著 在讀取緩存時 無法根據(jù)當(dāng)前緩存key 找到之前的緩存,從而使得失效
3. 解決方案
3.1 原理
在 生成緩存Key 的id參數(shù) 前,將 帶有token參數(shù)的圖片Url地址 去掉 token參數(shù),從而根據(jù) 初始的圖片Url地址 生成緩存Key的id參數(shù)實現(xiàn)了一個圖片的緩存Key的id參數(shù)始終唯一 ,即等于 圖片Url地址
3.2 儲備知識:生成緩存Key的id參數(shù)的邏輯
生成緩存Key的id參數(shù)的邏輯為:直接將圖片的 URL 地址作為緩存Key的id參數(shù)public?class?Engine?implements?EngineJobListener,
MemoryCache.ResourceRemovedListener,
EngineResource.ResourceListener?{
public??LoadStatus?load(Key?signature,?int?width,?int?height,?DataFetcher?fetcher,
DataLoadProvider?loadProvider,?Transformation?transformation,?ResourceTranscoder?transcoder,
Priority?priority,?boolean?isMemoryCacheable,?DiskCacheStrategy?diskCacheStrategy,?ResourceCallback?cb)?{
Util.assertMainThread();
long?startTime?=?LogTime.getLogTime();
final?String?id?=?fetcher.getId();
//?獲得了一個id字符串,即需加載圖片的唯一標(biāo)識
//?如,若圖片的來源是網(wǎng)絡(luò),那么該id?=?這張圖片的url地址
//?fetcher?=?HttpUrlFetcher的實例,即調(diào)用HttpUrlFetcher.getid()->>分析19
EngineKey?key?=?keyFactory.buildKey(id,?signature,?width,?height,?loadProvider.getCacheDecoder(),loadProvider.getSourceDecoder(),?transformation,?loadProvider.getEncoder(),transcoder,?loadProvider.getSourceEncoder());
//?將該id?和?signature、width、height等10個參數(shù)一起傳入到緩存Key的工廠方法里,最終創(chuàng)建出一個EngineKey對象
//?創(chuàng)建原理:通過重寫equals()?和?hashCode(),保證只有傳入EngineKey的所有參數(shù)都相同情況下才認(rèn)為是同一個EngineKey對象
//?該EngineKey?即Glide中的緩存Key
...
}
public?class?HttpUrlFetcher?implements?DataFetcher?{
...
private?final?GlideUrl?glideUrl;
//?GlideUrl?=?在上篇文章講解?圖片加載?第2步load()中傳入圖片url地址時,Glide在內(nèi)部把圖片url地址包裝成一個GlideUrl對象
@Override
public?String?getId()?{
return?glideUrl.getCacheKey();
//?->>分析20
}
public?class?GlideUrl?{
private?final?URL?url;
private?final?String?stringUrl;
...
//?GlideUrl構(gòu)造函數(shù)
public?GlideUrl(URL?url)?{
this(url,?Headers.DEFAULT);
}
public?GlideUrl(String?url)?{
this(url,?Headers.DEFAULT);
}
public?String?getCacheKey()?{
return?stringUrl?!=?null???stringUrl?:?url.toString();
//?在生成GlideUrl對象時:
//?若傳入的是URL字符串(即圖片地址),就直接返回該字符串(大多數(shù)是這種情況)
//?若傳入的是URL對象,那么就返回這個對象toString()后的結(jié)果。
}
...
}
3.3 實現(xiàn)方案
即 我們只需重寫getCacheKey() & 將 帶有token參數(shù)的圖片Url地址 去掉 token參數(shù) 即可。/**
*?代碼實現(xiàn):創(chuàng)建一個GlideUrl類的子類?&?重寫getCacheKey()
**/
//?1.?繼承GlideUrl
public?class?mGlideUrl?extends?GlideUrl?{
private?String?mUrl;
//?構(gòu)造函數(shù)里?傳入?帶有token參數(shù)的圖片Url地址
public?MyGlideUrl(String?url)?{
super(url);
mUrl?=?url;
}
//?2.?重寫getCacheKey()
@Override
public?String?getCacheKey()?{
return?mUrl.replace(deleteToken(),?"");
//?通過?deleteToken()?從?帶有token參數(shù)的圖片Url地址中?去掉?token參數(shù)
//?最終返回一個沒有token參數(shù)、初始的圖片URL地址
//?->>分析1
}
//?分析1:deleteToken()
private?String?deleteToken()?{
String?tokenParam?=?"";
int?tokenKeyIndex?=?mUrl.indexOf("?token=")?>=?0???mUrl.indexOf("?token=")?:?mUrl.indexOf("&token=");
if?(tokenKeyIndex?!=?-1)?{
int?nextAndIndex?=?mUrl.indexOf("&",?tokenKeyIndex?+?1);
if?(nextAndIndex?!=?-1)?{
tokenParam?=?mUrl.substring(tokenKeyIndex?+?1,?nextAndIndex?+?1);
}?else?{
tokenParam?=?mUrl.substring(tokenKeyIndex);
}
}
return?tokenParam;
}
}
/**
*?使用緩存時:需要在load()中傳入自定義的?mGlideUrl對象
**/
Glide.with(this)
.load(new?mGlideUrl(url))
.into(imageView);
//?注:a.?若像之前直接傳入圖片的url地址,那么在內(nèi)部還是會使用原始的GlideUrl類
//????b.?即直接將傳入傳入圖片的url地址作為緩存key的Id參數(shù),而沒有對token參數(shù)作任何處理
4. 總結(jié)本文主要對Glide的圖片緩存功能的使用問題進(jìn)行講解
總結(jié)
以上是生活随笔為你收集整理的android glide的历史,Android 图片加载的那些事:为什么你的Glide 缓存没有起作用?...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: html怎么设置单选框样式,CSS -
- 下一篇: web站点放入html页面,HTML