github源碼地址:https://github.com/zhou-you/RxEasyHttp
緩存使用
緩存介紹
本庫(kù)的緩存主要分okhttp的Cache緩存和自定義的RxCache緩存,大家有疑問(wèn)okhttp有緩存,retrofit也是支持通過(guò)header來(lái)設(shè)置緩存,為什么還要自定義一個(gè)緩存機(jī)制呢?通過(guò)自定義RxCache緩存使用更簡(jiǎn)單,更符合我們常用的業(yè)務(wù)需求(常用的緩存策略也不會(huì)太復(fù)雜), retrofit的緩存借助于okhttp通過(guò)攔截器interceptor實(shí)現(xiàn)或者通過(guò)@Headers("Cache-Control: public, max-age=3600)
具體用法這里不做詳細(xì)描述,有興趣的可以自己去了解。動(dòng)態(tài)修改緩存時(shí)間不方便,例如:同一個(gè)接口,不同時(shí)間段請(qǐng)求的內(nèi)容緩存的時(shí)間不一樣,需要?jiǎng)討B(tài)修改。
對(duì)于DEFAULT
模式是okhttp的Cache緩存。因?yàn)樵撃J绞峭耆裱瓨?biāo)準(zhǔn)的http協(xié)議的,緩存時(shí)間是依靠服務(wù)端響應(yīng)頭來(lái)控制,也可以通過(guò)攔截器自己處理
對(duì)于RxCache的緩存支持多種存儲(chǔ)方式,提供IDiskConverter
轉(zhuǎn)換器接口目前支持SerializableDiskConverter
和GsonDiskConverter
兩種方式,也可以自定義Parcelable、fastjson、xml、kryo等轉(zhuǎn)換器
SerializableDiskConverter
使用緩存前,必須讓緩存的數(shù)據(jù)所有javaBean對(duì)象實(shí)現(xiàn)Serializable接口,否則會(huì)報(bào)NotSerializableException。 因?yàn)榫彺娴脑硎菍?duì)象序列化后保存,如果不實(shí)現(xiàn)Serializable接口,會(huì)導(dǎo)致對(duì)象無(wú)法序列化,進(jìn)而無(wú)法保存,也就達(dá)不到緩存的效果。
優(yōu)點(diǎn):存儲(chǔ)和讀取都不用再轉(zhuǎn)化直接就是需要的對(duì)象速度快
缺點(diǎn):如果javabean里面還有javabean且層級(jí)比較多,也必須每個(gè)都要實(shí)現(xiàn)Serializable接口,比較麻煩
GsonDiskConverter
此種方式就是以json字符串的方式存儲(chǔ)
優(yōu)點(diǎn):相對(duì)于SerializableDiskConverter轉(zhuǎn)換器,存儲(chǔ)的對(duì)象不需要進(jìn)行序列化
缺點(diǎn):就是存儲(chǔ)和讀取都要使用Gson進(jìn)行轉(zhuǎn)換,object->String->Object的給一個(gè)過(guò)程,相對(duì)來(lái)說(shuō)每次都要轉(zhuǎn)換性能略低,但是性能基本忽略不計(jì)
目前提供了七種CacheMode緩存模式,每種緩存模式都可以指定對(duì)應(yīng)的CacheTime,將復(fù)雜常用的業(yè)務(wù)場(chǎng)景封裝在里面,讓你不用關(guān)心緩存的具體實(shí)現(xiàn),而專(zhuān)注于數(shù)據(jù)的處理
- NO_CACHE:不使用緩存,該模式下,cacheKey,cacheTime 等參數(shù)均無(wú)效
- DEFAULT:按照HTTP協(xié)議的默認(rèn)緩存規(guī)則,走OKhttp的Cache緩存
- FIRSTREMOTE:先請(qǐng)求網(wǎng)絡(luò),請(qǐng)求網(wǎng)絡(luò)失敗后再加載緩存
- FIRSTCACHE:先加載緩存,緩存沒(méi)有再去請(qǐng)求網(wǎng)絡(luò)
- ONLYREMOTE:僅加載網(wǎng)絡(luò),但數(shù)據(jù)依然會(huì)被緩存
- ONLYCACHE:只讀取緩存,緩存沒(méi)有會(huì)返回null
- CACHEANDREMOTE:先使用緩存,不管是否存在,仍然請(qǐng)求網(wǎng)絡(luò),CallBack會(huì)回調(diào)兩次.
注:無(wú)論對(duì)于哪種緩存模式,都可以指定一個(gè)cacheKey,建議針對(duì)不同需要緩存的頁(yè)面設(shè)置不同的cacheKey,如果相同,會(huì)導(dǎo)致數(shù)據(jù)覆蓋。
緩存設(shè)置
緩存設(shè)置有兩種方式
方式一:全局設(shè)置,所有請(qǐng)求都會(huì)默認(rèn)使用此模式
EasyHttp.getInstance()
...
.setCacheMode(CacheMode.CACHEANDREMOTE)//不設(shè)置默認(rèn)是NO_CACHE模式
...
方式二:?jiǎn)蝹€(gè)請(qǐng)求設(shè)置緩存模式
EasyHttp.get(URL)
...
.cacheMode(CacheMode.FIRSTREMOTE)
...
設(shè)置轉(zhuǎn)換器
方式一:全局設(shè)置,所有請(qǐng)求都會(huì)默認(rèn)使用此存儲(chǔ)轉(zhuǎn)換器
EasyHttp.getInstance().setCacheDiskConverter(new SerializableDiskConverter())//默認(rèn)緩存使用序列化轉(zhuǎn)化
方式二:?jiǎn)蝹€(gè)請(qǐng)求設(shè)置存儲(chǔ)轉(zhuǎn)換器
EasyHttp.get(URL).cacheDiskConverter(new GsonDiskConverter());
注:一個(gè)請(qǐng)求就選用一種轉(zhuǎn)換器,切記不要使用SerializableDiskConverter來(lái)緩存,又用GsonDiskConverter來(lái)讀會(huì)報(bào)錯(cuò)
自定義轉(zhuǎn)換器
如果你想擁有自己的轉(zhuǎn)換器請(qǐng)實(shí)現(xiàn)IDiskConverter
接口。
示例:
public class CustomDiskConverter implements IDiskConverter {
@Override
public <T> T load(InputStream source, Type type) {
//實(shí)現(xiàn)讀功能
return null;
}
@Override
public boolean writer(OutputStream sink, Object data) {
//實(shí)現(xiàn)寫(xiě)功能
return false;
}
}
緩存回調(diào)
對(duì)具有緩存的回調(diào)CallBack,如果你想知道當(dāng)前的緩存是來(lái)自本地還是網(wǎng)絡(luò),只需要回調(diào)中加入CacheResult,其它和普通的網(wǎng)絡(luò)請(qǐng)求方式一模一樣。CacheResult中的isFromCache可以知道是否來(lái)自緩存,true:來(lái)自緩存,false:來(lái)自網(wǎng)絡(luò)。請(qǐng)使用new SimpleCallBack<CacheResult<T>>()
也就是在你原有的T上包含一層CacheResult就可以了。如果不想用到isFromCache就不需要用CacheResult,直接使用new SimpleCallBack<T>()
帶有CacheResult回調(diào)示例:
EasyHttp.get(url)
.readTimeOut(30 * 1000)//測(cè)試局部讀超時(shí)30s
.cacheMode(cacheMode)
.cacheKey(this.getClass().getSimpleName())//緩存key
.retryCount(5)//重試次數(shù)
.cacheTime(5 * 60)//緩存時(shí)間300s,默認(rèn)-1永久緩存 okhttp和自定義緩存都起作用
//.okCache(new Cache());//okhttp緩存,模式為默認(rèn)模式(CacheMode.DEFAULT)才生效
//.cacheDiskConverter(new GsonDiskConverter())//默認(rèn)使用的是 new SerializableDiskConverter();
.cacheDiskConverter(new SerializableDiskConverter())//默認(rèn)使用的是 new SerializableDiskConverter();
.timeStamp(true)
.execute(new SimpleCallBack<CacheResult<SkinTestResult>>() {
@Override
public void onError(ApiException e) {
//請(qǐng)求失敗
}
@Override
public void onSuccess(CacheResult<SkinTestResult> cacheResult) {
HttpLog.i(cacheResult.toString());
String from = "";
if (cacheResult.isFromCache) {
from = "我來(lái)自緩存";
} else {
from = "我來(lái)自遠(yuǎn)程網(wǎng)絡(luò)";
}
....
}
});
移除緩存
支持根據(jù)緩存key移除緩存,主要是針對(duì)RxCache才能起作用
EasyHttp.removeCache("cachekey");
清空緩存
EasyHttp.clearCache();
RxCache
RxCache是自己封裝的一個(gè)本地緩存功能庫(kù),采用Rxjava+DiskLruCache來(lái)實(shí)現(xiàn),線程安全內(nèi)部采用ReadWriteLock機(jī)制防止頻繁讀寫(xiě)緩存造成的異常,可以獨(dú)立使用,單獨(dú)用RxCache來(lái)存儲(chǔ)數(shù)據(jù)。采用transformer與網(wǎng)絡(luò)請(qǐng)求結(jié)合,可以實(shí)現(xiàn)網(wǎng)絡(luò)緩存功能,本地硬緩存,具有緩存讀寫(xiě)功能(異步)、緩存是否存在、根據(jù)key刪除緩存、清空緩存(異步)、緩存Key會(huì)自動(dòng)進(jìn)行MD5加密、可以設(shè)置緩存磁盤(pán)大小、緩存key、緩存時(shí)間、緩存存儲(chǔ)的轉(zhuǎn)換器、緩存目錄、緩存Version等功能本庫(kù)不作為重點(diǎn)介紹。后期會(huì)將此代碼獨(dú)立開(kāi)源一個(gè)庫(kù),作為一分鐘讓你自己的網(wǎng)絡(luò)庫(kù)也具有緩存功能,敬請(qǐng)期待!!!