github源码地址:https://github.com/zhou-you/RxEasyHttp
缓存使用
缓存介绍
本库的缓存主要分okhttp的Cache缓存和自定义的RxCache缓存,大家有疑问okhttp有缓存,retrofit也是支持通过header来设置缓存,为什么还要自定义一个缓存机制呢?通过自定义RxCache缓存使用更简单,更符合我们常用的业务需求(常用的缓存策略也不会太复杂), retrofit的缓存借助于okhttp通过拦截器interceptor实现或者通过@Headers("Cache-Control: public, max-age=3600)
具体用法这里不做详细描述,有兴趣的可以自己去了解。动态修改缓存时间不方便,例如:同一个接口,不同时间段请求的内容缓存的时间不一样,需要动态修改。
对于DEFAULT
模式是okhttp的Cache缓存。因为该模式是完全遵循标准的http协议的,缓存时间是依靠服务端响应头来控制,也可以通过拦截器自己处理
对于RxCache的缓存支持多种存储方式,提供IDiskConverter
转换器接口目前支持SerializableDiskConverter
和GsonDiskConverter
两种方式,也可以自定义Parcelable、fastjson、xml、kryo等转换器
SerializableDiskConverter
使用缓存前,必须让缓存的数据所有javaBean对象实现Serializable接口,否则会报NotSerializableException。 因为缓存的原理是将对象序列化后保存,如果不实现Serializable接口,会导致对象无法序列化,进而无法保存,也就达不到缓存的效果。
优点:存储和读取都不用再转化直接就是需要的对象速度快
缺点:如果javabean里面还有javabean且层级比较多,也必须每个都要实现Serializable接口,比较麻烦
GsonDiskConverter
此种方式就是以json字符串的方式存储
优点:相对于SerializableDiskConverter转换器,存储的对象不需要进行序列化
缺点:就是存储和读取都要使用Gson进行转换,object->String->Object的给一个过程,相对来说每次都要转换性能略低,但是性能基本忽略不计
目前提供了七种CacheMode缓存模式,每种缓存模式都可以指定对应的CacheTime,将复杂常用的业务场景封装在里面,让你不用关心缓存的具体实现,而专注于数据的处理
- NO_CACHE:不使用缓存,该模式下,cacheKey,cacheTime 等参数均无效
- DEFAULT:按照HTTP协议的默认缓存规则,走OKhttp的Cache缓存
- FIRSTREMOTE:先请求网络,请求网络失败后再加载缓存
- FIRSTCACHE:先加载缓存,缓存没有再去请求网络
- ONLYREMOTE:仅加载网络,但数据依然会被缓存
- ONLYCACHE:只读取缓存,缓存没有会返回null
- CACHEANDREMOTE:先使用缓存,不管是否存在,仍然请求网络,CallBack会回调两次.
注:无论对于哪种缓存模式,都可以指定一个cacheKey,建议针对不同需要缓存的页面设置不同的cacheKey,如果相同,会导致数据覆盖。
缓存设置
缓存设置有两种方式
方式一:全局设置,所有请求都会默认使用此模式
EasyHttp.getInstance()
...
.setCacheMode(CacheMode.CACHEANDREMOTE)//不设置默认是NO_CACHE模式
...
方式二:单个请求设置缓存模式
EasyHttp.get(URL)
...
.cacheMode(CacheMode.FIRSTREMOTE)
...
设置转换器
方式一:全局设置,所有请求都会默认使用此存储转换器
EasyHttp.getInstance().setCacheDiskConverter(new SerializableDiskConverter())//默认缓存使用序列化转化
方式二:单个请求设置存储转换器
EasyHttp.get(URL).cacheDiskConverter(new GsonDiskConverter());
注:一个请求就选用一种转换器,切记不要使用SerializableDiskConverter来缓存,又用GsonDiskConverter来读会报错
自定义转换器
如果你想拥有自己的转换器请实现IDiskConverter
接口。
示例:
public class CustomDiskConverter implements IDiskConverter {
@Override
public T load(InputStream source, Type type) {
//实现读功能
return null;
}
@Override
public boolean writer(OutputStream sink, Object data) {
//实现写功能
return false;
}
}
缓存回调
对具有缓存的回调CallBack,如果你想知道当前的缓存是来自本地还是网络,只需要回调中加入CacheResult,其它和普通的网络请求方式一模一样。CacheResult中的isFromCache可以知道是否来自缓存,true:来自缓存,false:来自网络。请使用new SimpleCallBack
也就是在你原有的T上包含一层CacheResult就可以了。如果不想用到isFromCache就不需要用CacheResult,直接使用new SimpleCallBack
带有CacheResult回调示例:
EasyHttp.get(url)
.readTimeOut(30 * 1000)//测试局部读超时30s
.cacheMode(cacheMode)
.cacheKey(this.getClass().getSimpleName())//缓存key
.retryCount(5)//重试次数
.cacheTime(5 * 60)//缓存时间300s,默认-1永久缓存 okhttp和自定义缓存都起作用
//.okCache(new Cache());//okhttp缓存,模式为默认模式(CacheMode.DEFAULT)才生效
//.cacheDiskConverter(new GsonDiskConverter())//默认使用的是 new SerializableDiskConverter();
.cacheDiskConverter(new SerializableDiskConverter())//默认使用的是 new SerializableDiskConverter();
.timeStamp(true)
.execute(new SimpleCallBack>() {
@Override
public void onError(ApiException e) {
//请求失败
}
@Override
public void onSuccess(CacheResult cacheResult) {
HttpLog.i(cacheResult.toString());
String from = "";
if (cacheResult.isFromCache) {
from = "我来自缓存";
} else {
from = "我来自远程网络";
}
....
}
});
移除缓存
支持根据缓存key移除缓存,主要是针对RxCache才能起作用
EasyHttp.removeCache("cachekey");
清空缓存
EasyHttp.clearCache();
RxCache
RxCache是自己封装的一个本地缓存功能库,采用Rxjava+DiskLruCache来实现,线程安全内部采用ReadWriteLock机制防止频繁读写缓存造成的异常,可以独立使用,单独用RxCache来存储数据。采用transformer与网络请求结合,可以实现网络缓存功能,本地硬缓存,具有缓存读写功能(异步)、缓存是否存在、根据key删除缓存、清空缓存(异步)、缓存Key会自动进行MD5加密、可以设置缓存磁盘大小、缓存key、缓存时间、缓存存储的转换器、缓存目录、缓存Version等功能本库不作为重点介绍。后期会将此代码独立开源一个库,作为一分钟让你自己的网络库也具有缓存功能,敬请期待!!!