“慢慢来才最快. ”
踩坑记录
前段时间将公司的项目架构重新改了一遍,改的途中肯定会遇到坑,记录下来总比烂在脑子里好
简单介绍一下RxCache,一个缓存库,Rx大家族中的一员。配合RxJava用起来很爽.
记录开始
使用RxCache的时候发现不支持泛型序列化。泛型的类大致如下
class Response<T> {
int code;
T data;
} 这是我现在见到的主流的封装网络请求返回体的格式,Data为可变的类型,其他的属性不变,问题在于RxCache不支持泛型的序列化,OK,我们来解决,既然你不支持泛型那我使用非泛型来缓存,所以我将Retrofit和RxCache的请求网络的代码变成了这样
RxCache
@LifeCache(duration = 5, timeUnit = TimeUnit.MINUTES)
Observable<Reply<JsonObject>> getHomePage(Observable<JsonObject> homePage, DynamicKey idLastUserQueried, EvictProvider evictProvider);
Retrofit
@FormUrlEncoded
@POST(HttpApi.NEWINDEX)
Observable<JsonObject> getHomePage(@FieldMap Map<String, String> maps);
这样发现确实可以缓存,但是我们使用起来很不方便,我们不可能拿着JSONObject去操作,这时候轮到RxJava登场,转换一下数据格式对于RxJava来说是很Easy的事.
RxJava
mRepositoryManager.obtainRxCacheService(CommonCache.class)
.getHomePage(homePage
, new DynamicKey(1) // 因为是首页 所以一般来说是固定的内容 五分钟自动刷新一次
, new EvictProvider(false)) // 如果为true 代表强制刷新 不获取缓存
.flatMap(new Function<Reply<JsonObject>, ObservableSource<BaseBean<IndexInfo>>>() {
@Override
public ObservableSource<BaseBean<IndexInfo>> apply(@NonNull Reply<JsonObject> jsonObjectReply) throws Exception {
return Observable.just(jsonObjectReply.getData(),BaseBean.class);
}
});
以为已经完了?
no,这才刚刚开始
现在的json解析库解析基本都是这么一句话
mGson.fromJson(jsonObjectReply.getData(),BaseBean.class)
对于普通的解析是够的,但是我们需要的类型是泛型的,所以后来我改成了这样
return Observable.just(mGson.fromJson(jsonObjectReply.getData(), new BaseBean<IndexInfo>().getClass()));
yes,我以为搞定了,已经不报错了不是吗?但是运行时开始报错了
Error:(62, 47) 错误: 不兼容的类型: Observable<BaseBean>无法转换为ObservableSource<BaseBean<IndexInfo>>
后面我明白泛型在运行时的getclass并不能取到泛型的class,OK此路不通,另路,与此同时我想到为什么Gson(我这里使用的是Gson)不能替我干这些事呢? 为什么他不能帮我去搞定呢?所以我发现了这种写法
Type objectType = new TypeToken<BaseBean<IndexInfo>>() {}.getType();
BaseBean<IndexInfo> indexInfoBaseBean = mGson.fromJson(jsonObjectReply.getData(), objectType);
return Observable.just(indexInfoBaseBean);
OK.That’s done.踩坑完毕
参考链接:
http://www.cnblogs.com/qq78292959/p/3781808.html
http://bbs.csdn.net/topics/390376611/
https://github.com/VictorAlbertos/RxCache/issues/41
2017/11/1 9:58:27 更新,前段时间项目又用到了缓存,安装上面的做法确实可以解决RxCache缓存泛型的问题,但是我觉得并不够优雅,在P层加了很多无关的东西,下面是在github上找到的另一个解决办法。
// 一般来说BaseBean都是长这样
public class BaseBean<T>{
String msg;
List<T> results;
}
// RxCache之所以不能解析T的类型是因为无法获取明确的类型,那我们给他一个明确的类型
public class ApiResponse extends BaseBean<ApiResponse.FocusListItem> {
public static class FocusListItem {
。。。
}
}
// Cache模块的接口
Observable<Reply<ApiResponse>> getFocusList(Observable<ApiResponse> observable, EvictProvider evictProvider);
亲测是有效的,记录下来,以备后记…