簡介
Library項(xiàng)目地址: rxcache
RxCache是一個本地緩存功能庫,采用Rxjava+DiskLruCache來實(shí)現(xiàn),線程安全內(nèi)部采用ReadWriteLock機(jī)制防止頻繁讀寫緩存造成的異常,可以獨(dú)立使用,單獨(dú)用RxCache來存儲數(shù)據(jù)。也可以采用transformer與retrofit網(wǎng)絡(luò)請求結(jié)合,讓你的網(wǎng)絡(luò)庫實(shí)現(xiàn)網(wǎng)絡(luò)緩存功能,而且支持適用于不同業(yè)務(wù)場景的六種緩存模式。
對于本地緩存,可以進(jìn)行緩存讀寫操作(異步或同步)、判斷緩存是否存在、根據(jù)key刪除緩存(異步或同步)、清空緩存(異步或同步)等。緩存Key會自動進(jìn)行MD5加密、可以提供設(shè)置緩存磁盤大小、緩存key、緩存時間、緩存存儲的轉(zhuǎn)換器、緩存目錄、緩存Version等功能。本庫不作為重點(diǎn)介紹。
本地緩存
1.全局緩沖初始化
使用RxCacheProvider來初始化app的全局緩沖配置
RxCacheProvider.getInstance()
.setCacheDirectory(new File(getExternalCacheDir(), "rxcache")) // 緩存目錄,必須
.setCacheDiskConverter(new GsonDiskConverter()) // 設(shè)置數(shù)據(jù)轉(zhuǎn)換器默認(rèn)使用GsonDiskConverter
.setCacheMaxSize(50 * 1024 * 1024) // 最大緩存空間,默認(rèn)50M
.setCacheVersion(1)// 緩存版本為1
.setCacheTime(-1) // 緩存時間,默認(rèn)-1表示永久緩存
.build();
2.同步寫入和讀取緩存
// 同步寫入緩存
Model model = new Model(110, "holen"); // 要緩存的javaBean
RxCacheProvider.put(CACHE_KEY, model);
// 同步讀取緩存
Model result = RxCacheProvider.get(CACHE_KEY, Model.class);
3.異步寫入和讀取緩存
// 異步寫入緩存
Model model = new Model(110, "holen");
RxCacheProvider.save(CACHE_KEY, model)
.subscribeOn(Schedulers.io())
.subscribe(new DefaultCacheObserver<Boolean>());
// 異步讀取緩存
RxCacheProvider.load(CACHE_KEY, Model.class)
.subscribeOn(Schedulers.io())
.subscribe(new Consumer<Model>() {
@Override
public void accept(Model result) throws Exception {
Log.d(TAG, "accept: " + result);
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
Log.e(TAG, "throwable: ", throwable);
}
});
4.設(shè)置保存時間
RxCacheProvider.put(CACHE_WITH_TIME_KEY, model, 10 * 1000); // 緩存10s
// or
RxCacheProvider.save(CACHE_WITH_TIME_KEY, model, 10 * 1000).subscribe(new DefaultCacheObserver<>());
5.使用CacheType類包裝緩存類型
List<Model> modelList = new ArrayList<>();
for (int i = 0; i < 3; i++) {
modelList.add(new Model(i, "holen" + i));
}
List<Model> result = RxCacheProvider.get(CACHE_WITH_TIME_KEY, new CacheType<List<Model>>(){});
6.同步或異步清楚緩存
// 同步清楚緩存
RxCacheProvider.removeCache(CACHE_KEY);
// 異步清楚緩存
RxCacheProvider.rxRemove(CACHE_KEY)
.subscribeOn(Schedulers.io())
.subscribe(new Consumer<Boolean>() {
@Override
public void accept(Boolean success) throws Exception {
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
}
});
7.判斷是否包含緩存
boolean contain = RxCacheProvider.containsKey(CACHE_KEY);
8.clear緩存
RxCacheProvider.clearCache();
// or
RxCacheProvider.rxClear()
.subscribe(new Consumer<Boolean>() {
@Override
public void accept(Boolean aBoolean) throws Exception {
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
}
});
9.獲取單獨(dú)的RxCache
RxCacheProvider中操作緩存的方法在RxCache中都有,因?yàn)镽xCacheProvider內(nèi)部就是通過RxCache來操作緩存的。
RxCache rxCache = RxCacheProvider.getRxCacheBuilder()
.diskConverter(new SerializableDiskConverter())
.build();
User user = new User(222, "Sherlock");
rxCache.save("user-cache", user);
網(wǎng)絡(luò)緩存
1.六種網(wǎng)絡(luò)緩存策略
- DEFAULT:不使用緩存,該模式下,cacheKey,cacheTime 等參數(shù)均無效
- FIRSTREMOTE:先請求網(wǎng)絡(luò),請求網(wǎng)絡(luò)失敗后再加載緩存
- FIRSTCACHE:先加載緩存,緩存沒有再去請求網(wǎng)絡(luò)
- ONLYREMOTE:僅加載網(wǎng)絡(luò),但數(shù)據(jù)依然會被緩存
- ONLYCACHE:只讀取緩存
- CACHEANDREMOTE:先使用緩存,不管是否存在,仍然請求網(wǎng)絡(luò),CallBack會回調(diào)兩次.
- CACHEANDREMOTEDISTINCT:先使用緩存,不管是否存在,仍然請求網(wǎng)絡(luò),CallBack回調(diào)不一定是兩次,如果發(fā)現(xiàn)請求的網(wǎng)絡(luò)數(shù)據(jù)和緩存數(shù)據(jù)是相同的,就不會再返回網(wǎng)絡(luò)的回調(diào),即只回調(diào)一次。若不相同仍然會回調(diào)兩次。(目的是為了防止數(shù)據(jù)沒有發(fā)生變化,也需要回調(diào)兩次導(dǎo)致界面無用的重復(fù)刷新)
注:無論對于哪種緩存模式,都可以指定一個cacheKey,建議針對不同需要緩存的頁面設(shè)置不同的cacheKey,如果相同,會導(dǎo)致數(shù)據(jù)覆蓋。
2.使用方法
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
GithubService githubService = retrofit.create(GithubService.class);
// 1.將寫好的retrofit的網(wǎng)絡(luò)請求接口的Observable對象直接傳入RxCacheProvider的api方法
// 2.配置緩存key、緩存模式、緩存時間等參數(shù)
// 3.調(diào)用buildCache,傳入需要緩存的類型,即可獲得一個具備緩存功能的Observable對象
RxCacheProvider.api(githubService.getUser("HolenZhou"))
.cacheKey(NetCacheActivity.class.getSimpleName())
.cacheMode(mRxCacheMode)
.cacheTime(5 * 60 * 1000) // 5min
.buildCache(User.class)
.subscribe(new Consumer<User>() {
@Override
public void accept(User user) throws Exception {
Log.d(TAG, "accept: " + user);
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
Log.e(TAG, "throwable: ", throwable);
}
});
3.設(shè)置回調(diào)中包含結(jié)果是否來自緩存的信息
RxCacheProvider.api(githubService.getUser("HolenZhou"))
.cacheKey(this.getClass().getSimpleName())
.cacheMode(mRxCacheMode)
.buildCache(new CacheCallback<User>(){})
.subscribe(new Consumer<CacheResult<User>>() {
@Override
public void accept(CacheResult<User> userCacheResult) throws Exception {
Log.d(TAG, "accept: " + userCacheResult);
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
Log.e(TAG, "throwable: " + throwable.getMessage(), throwable);
}
});
4.分頁緩存
RxCacheProvider.api(githubService.getUser("HolenZhou"))
.dynamicKey(new DynamicKey(NetCacheActivity.class.getSimpleName(), PAGE_NUM))
.cacheMode(mRxCacheMode)
.buildCache(User.class)
.subscribe(new Consumer<User>() {
@Override
public void accept(User user) throws Exception {
Log.d(TAG, "accept: " + user);
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
Log.e(TAG, "throwable: ", throwable);
}
});
5.分賬戶緩存
RxCacheProvider.api(githubService.getUser("HolenZhou"))
.dynamicKey(new DynamicKey(NetCacheActivity.class.getSimpleName(), account))
.cacheMode(mRxCacheMode)
.buildCache(User.class)
.subscribe(new Consumer<User>() {
@Override
public void accept(User user) throws Exception {
Log.d(TAG, "accept: " + user);
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
Log.e(TAG, "throwable: ", throwable);
}
});
參考
https://github.com/zhou-you/RxEasyHttp/wiki/cache#%E7%BC%93%E5%AD%98%E4%BD%BF%E7%94%A8