RxJava+Retrofit+OkHttp深入浅出-终极封装五(数据持久化)_第1页
RxJava+Retrofit+OkHttp深入浅出-终极封装五(数据持久化)_第2页
RxJava+Retrofit+OkHttp深入浅出-终极封装五(数据持久化)_第3页
RxJava+Retrofit+OkHttp深入浅出-终极封装五(数据持久化)_第4页
RxJava+Retrofit+OkHttp深入浅出-终极封装五(数据持久化)_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、RxJava+Retrofit+OkHttp深入浅出-终极封装五(数据持久化)第一次请求是网络加载,之后只要在设置的保鲜时间以内都是通过缓存拉取数据,提高加载速度!下面我们分两节讲解,一节讲述自带的retrofit-cache用法和缺陷,一节讲述自己定义的缓存处理方案Retrofit-cookie由于retrofit是基于okhttp的,所以他的cache原理就是运用了okhttp的cookie处理;注意:这里自带的cookie前提是服务器提供了支持(返回头有cache信息),只有get请求才具备http的缓存功能,post没有!没有!没有Retrofit-Cache的内容1.http缓存相关

2、头: Expires (实体标头,HTTP 1.0+):一个GMT时间,试图告知客户端,在此日期内,可以信任并使用对应缓存中的副本,缺点是,一但客户端日期不准确.则可能导致失效2.Pragma : no-cache(常规标头,http1.0+)3.Cache-Control : (常规标头,HTTP1.1) 3.1public:(仅为响应标头)响应:告知任何途径的缓存者,可以无条件的缓存该响应 3.2private(仅为响应标头):响应:告知缓存者(据我所知,是指用户代理,常见浏览器的本地缓存.用户也是指,系统用户.但也许,不应排除,某些网关,可以识别每个终端用户的情况),只针对单个用户缓存响

3、应. 且可以具体指定某个字段.如private “username”,则响应头中,名为username的标头内容,不会被共享缓存. 3.3no-cache:告知缓存者,必须原原本本的转发原始请求,并告知任何缓存者,别直接拿你缓存的副本,糊弄人.你需要去转发我的请求,并验证你的缓存(如果有的话).对应名词:端对端重载.cache-retrofit使用注解使用,具体方法具体设置(max-age设置的是保鲜时间)Headers(Cache-Control: max-age=640000)GET(widget/list)CallList widgetList();当然我们肯定想要动态设置,而且每一个g

4、et方法都需要缓存保鲜处理,怎么解决呢?1.开辟一片本地空间,设置给OkHttpClient.Builder OkHttpClient.Builder builder = new OkHttpClient.Builder(); /*缓存位置和大小*/ builder.cache(new Cache(MyApplication.app.getCacheDir(),10*1024*1024);2.设置拦截器,请求前判断网络,拦截数据和返回本地数据网上很多资源都是错误的,走了很多弯路,注意这里一定要返回一个新的Response 不让不会有结果显示/* * get缓存方式拦截器 * Created b

5、y WZG on 2016/10/26. */public class CacheInterceptor implements Interceptor Override public Response intercept(Chain chain) throws IOException Request request = chain.request(); if (!isNetworkAvailable(MyApplication.app) /没网强制从缓存读取(必须得写,不然断网状态下,退出应用,或者等待一分钟后,就获取不到缓存) request = request.newBuilder() .

6、cacheControl(CacheControl.FORCE_CACHE) .build(); Response response = ceed(request); Response responseLatest; if (isNetworkAvailable(MyApplication.app) int maxAge = 60; /有网失效一分钟 responseLatest = response.newBuilder() .removeHeader(Pragma) .removeHeader(Cache-Control) .header(Cache-Control, p

7、ublic, max-age= + maxAge) .build(); else int maxStale = 60 * 60 * 6; / 没网失效6小时 responseLatest= response.newBuilder() .removeHeader(Pragma) .removeHeader(Cache-Control) .header(Cache-Control, public, only-if-cached, max-stale= + maxStale) .build(); return responseLatest; 有网情况下,一分钟内访问的请求不会去真正http请求,而是

8、从cache中获取; 没网情况下,一律从缓存获取,6小时过期时间。3.设置OkHttpClient.Builder设置拦截器addNetworkInterceptor在请求发生前和发生后都处理一遍,addInterceptor在有结果返回后处理一遍 注意:这里一定要两个方法同时设置才能保证生效,暂时没搞懂为什么 OkHttpClient.Builder builder = new OkHttpClient.Builder(); builder.addNetworkInterceptor(new CacheInterceptor(); builder.addInterceptor(new Cac

9、heInterceptor();现在你的retrofit就能自动给get添加cookie了!总结自带数据持久化处理方便快捷简单,但是局限性太大,必须是get请求而且还需要服务器配合头文件返回处理,所以在实际开发中并不适用;所以才有了自定义cookie处理的方案自定义本地数据持久化方案思路主要是通过greenDao数据库存放数据,在网络请求成功后保存数据,再次请求判断url是否已经存在缓存数据 有网络:onstart中判断再判断保鲜时间,如果有效返回缓存数据,无效则再一次请求数据! 无网络(包含各种失败):onError中判断处理,有效时间内返回数据,无效自定义的网络错误抛出异常!1.创建缓存对

10、象数据记录返回数据,标识url,和缓存时间/* * post請求緩存数据 * Created by WZG on 2016/10/26. */Entitypublic class CookieResulte Id private long id; /*url*/ private String url; /*返回结果*/ private String resulte; /*时间*/ private long time; 2.BaseApi添加缓存相关设置参数保持和封装1-4封装的一致性,将缓存的相关设置放入在BaseApi中,并且将baseUrl和超时connectionTime也包含进来,更加

11、灵活/* * 请求数据统一封装类 * Created by WZG on 2016/7/16. */public abstract class BaseApi implements Func1BaseResultEntity, T /rx生命周期管理 private SoftReference rxAppCompatActivity; /*回调*/ private SoftReference listener; /*是否能取消加载框*/ private boolean cancel; /*是否显示加载框*/ private boolean showProgress; /*是否需要缓存处理*/

12、private boolean cache; /*基础url*/ private String baseUrl= /*方法-如果需要缓存必须设置这个参数;不需要不用設置*/ private String mothed; /*超时时间-默认6秒*/ private int connectionTime = 6; /*有网情况下的本地缓存时间默认60秒*/ private int cookieNetWorkTime=60; /*无网络的情况下本地缓存时间默认30天*/ private int cookieNoNetWorkTime=24*60*60*30;注意:如果需要使用缓存功能必须要设置mot

13、hed参数(和baseurl拼成一个url标识缓存数据)3.拦截Gson数据由于使用GsonConverterFactory自动解析数据,所以需要在自动转换前得到服务器返回的数据,我们可以自定义Interceptor在addInterceptor(成功后调用)拦截数据,保存到本地数据库中!/* * gson持久化截取保存数据 * Created by WZG on 2016/10/20. */public class CookieInterceptor implements Interceptor private CookieDbUtil dbUtil; /*是否缓存标识*/ private

14、boolean cache; public CookieInterceptor( boolean cache) dbUtil=CookieDbUtil.getInstance(); this.cache=cache; Override public Response intercept(Chain chain) throws IOException Request request = chain.request(); Response response = ceed(request); if(che) ResponseBody body = response.body();

15、BufferedSource source = body.source(); source.request(Long.MAX_VALUE); / Buffer the entire body. Buffer buffer = source.buffer(); Charset charset = Charset.defaultCharset(); MediaType contentType = body.contentType(); if (contentType != null) charset = contentType.charset(charset); String bodyString

16、 = buffer.clone().readString(charset); String url = request.url().toString(); CookieResulte resulte= dbUtil.queryCookieBy(url); long time=System.currentTimeMillis(); /*保存和更新本地数据*/ if(resulte=null) resulte =new CookieResulte(url,bodyString,time); dbUtil.saveCookie(resulte); else resulte.setResulte(bo

17、dyString); resulte.setTime(me); dbUtil.updateCookie(resulte); return response; 4.添加回调方法因为缓存回调过程中无法手动传递Gson对象,也就是ResulteEntity中的T泛型,所以自由单独添加一个方法,返回缓存数据!考虑到可能不需要回到所以写成了具体的方法,可主动覆盖!/* * 成功回调处理 * Created by WZG on 2016/7/16. */public abstract class HttpOnNextListener /* * 成功后回调方法 * param t */ public abs

18、tract void onNext(T t); /* * 緩存回調結果 * param string */ public void onCacheNext(String string) *5.数据持久化调用,获取缓存这里分两种情况,有网络-和无网络(包含各种失败不单单只是无网络)有网 判断是否存在缓存,如果有判断保鲜时间,有效期内返回数据,失效在一起请求; /* * 订阅开始时调用 * 显示ProgressDialog */ Override public void onStart() showProgressDialog(); /*缓存并且有网*/ if(api.isCache()& App

19、Util.isNetworkAvailable(MyApplication.app) /*获取缓存数据*/ CookieResulte cookieResulte= CookieDbUtil.getInstance().queryCookieBy(api.getUrl(); if(cookieResulte!=null) long time= (System.currentTimeMillis()-cookieResulte.getTime()/1000; if(time api.getCookieNetWorkTime() if( mSubscriberOnNextListener.get(

20、)!=null) mSubscriberOnNextListener.get().onCacheNext(cookieResulte.getResulte(); onCompleted(); unsubscribe(); 无网络(失败情况) 原理和有网络一样,但是额外的加入了rx异常处理,防止用户在处理工程中导致错误崩溃!并且无缓冲抛出自定义异常 /* * 对错误进行统一处理 * 隐藏ProgressDialog * * param e */ Override public void onError(Throwable e) dismissProgressDialog(); /*需要緩存并且本

21、地有缓存才返回*/ if(api.isCache() Observable.just(api.getUrl().subscribe(new Subscriber() Override public void onCompleted() Override public void onError(Throwable e) errorDo(e); Override public void onNext(String s) /*获取缓存数据*/ CookieResulte cookieResulte= CookieDbUtil.getInstance().queryCookieBy(s); if(cookieResulte=null) throw new HttpTimeException(网络错误); long time= (System.currentTimeMillis()-cookieResulte.getTime()/1000; if(timeapi.getCookieNoNetWorkTime() if( mSubscriberOnNextListener.get()!=null) mSubscriberOnNextListener.get().o

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论