Android中okhttp3.4.1+retrofit2.1.0实现离线缓存

Android中okhttp3.4.1+retrofit2.1.0实现离线缓存,第1张

概述关于Retrofit+OkHttp的强大这里就不多说了,还没了解的同学可以自行去百度。这篇文章主要讲如何利用Retrofit+OkHttp来实现一个较为简单的缓存策略:

关于Retrofit+Okhttp的强大这里就不多说了,还没了解的同学可以自行去百度。这篇文章主要讲如何利用Retrofit+Okhttp来实现一个较为简单的缓存策略:
即有网环境下我们请求数据时,如果没有缓存或者缓存过期了,就去服务器拿数据,并且将新缓存保存下来,如果有缓存而且没有过期,则直接使用缓存。无网环境下我们请求数据时,缓存没过期则直接使用缓存,缓存过期了则无法使用,需要重新联网获取服务器数据。

缓存处理还是很有必要的,它有效的减少服务器负荷,降低延迟提升用户体验,同时也方便用户即使在没网络的情况下也能使用APP。

之前一直有一个疑惑,既然Retrofit已经是对Okhttp的一个封装了,为什么还一直说Retrofit+Okhttp要一起搭配使用,后来才知道其实OKhttp很重要的一个作用,就是对一些网络请求的配置,例如连接超时,读取超时,以及一些缓存配置等。

一、添加依赖

compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile 'com.squareup.okhttp3:okhttp:3.4.1'
compile 'com.squareup.okhttp3:logging-interceptor:3.4.1' 

二、配置OkhttpClIEnt(设置缓存路径和缓存文件大小)

file httpCacheDirectory = new file(Environment.getExternalStorageDirectory(),"httpCache");//这里为了方便直接把文件放在了SD卡根目录的httpCache中,一般放在context.getCacheDir()中int cacheSize = 10 * 1024 * 1024;//设置缓存文件大小为10MCache cache = new Cache(httpCacheDirectory,cacheSize);httpClIEnt = new OkhttpClIEnt.Builder()    .connectTimeout(10,TimeUnit.SECONDS)//设置连接超时    .readTimeout(10,TimeUnit.SECONDS)//读取超时    .writeTimeout(10,TimeUnit.SECONDS)//写入超时    .addNetworkInterceptor(REWRITE_CACHE_CONTRol_INTERCEPTOR)//添加自定义缓存拦截器(后面讲解),注意这里需要使用.addNetworkInterceptor    .cache(cache)//把缓存添加进来    .build();

三、配置Retrofit

retrofit = new Retrofit.Builder()    .baseUrl(baseUrl)    .clIEnt(httpClIEnt)//把OkhttpClIEnt添加进来    .addConverterFactory(GsonConverterFactory.create())    .build();

四、编写拦截器

  我们知道其实Retrofit+Okhttp的缓存主要通过拦截器实现,所以主要做的功夫也在拦截器里面。

 static Interceptor REWRITE_CACHE_CONTRol_INTERCEPTOR = new Interceptor() {  @OverrIDe  public Response intercept(Chain chain) throws IOException {   Request request = chain.request();   //网上很多示例代码都对在request请求前对其进行无网的判断,其实无需判断,无网自动访问缓存//   if(!NetworkUtil.getInstance().isConnected()){//    request = request.newBuilder()//      .cacheControl(CacheControl.FORCE_CACHE)//只访问缓存//      .build();//   }   Response response = chain.proceed(request);   if (NetworkUtil.getInstance().isConnected()) {    int maxAge = 60;//缓存失效时间,单位为秒    return response.newBuilder()      .removeheader("Pragma")//清除头信息,因为服务器如果不支持,会返回一些干扰信息,不清除下面无法生效      .header("Cache-Control","public,max-age=" + maxAge)      .build();   } else {    //这段代码设置无效//    int maxStale = 60 * 60 * 24 * 28; // 无网络时,设置超时为4周//    return response.newBuilder()//      .header("Cache-Control",only-if-cached,max-stale=" + maxStale)//      .removeheader("Pragma")//      .build();   }   return response;  } };

到这里,其实已经可以实现了我们开头所说的缓存效果了。

  但是,上面设置的每个接口缓存时间都一样,例如我现在想让不同接口的缓存数据失效时间都不一样,甚至有些接口不缓存数据,应该怎么做呢?其实也很简单

首先我们只需要在接口前面添加@headers参数(max-age代表缓存时间,单位为秒,示例中表示缓存失效时间为60s,想要多少时间可以自行设置),不设置@headers参数则不进行缓存

 @headers("Cache-Control:public,max-age=60") @GET("getBusiness.action")//商店信息 Call<RestaurantInfoModel> getRestaurantInfo(@query("userID") String userID,@query("businessID") String businessID);

 同时,我们的缓存拦截器也要做下简单的修改(去掉了之前的注释代码)

 static Interceptor REWRITE_CACHE_CONTRol_INTERCEPTOR = new Interceptor() {  @OverrIDe  public Response intercept(Chain chain) throws IOException {   Request request = chain.request();   Response response = chain.proceed(request);   if (NetworkUtil.getInstance().isConnected()) {    //获取头部信息    String cacheControl =request.cacheControl().toString();    return response.newBuilder()      .removeheader("Pragma")//清除头信息,因为服务器如果不支持,会返回一些干扰信息,不清除下面无法生效      .header("Cache-Control",cacheControl)      .build();   }   return response;  } };

*注意:

1.只能缓存Get请求的接口,不能缓存Post请求的接口

2.OkhttpClIEnt需要用.addNetworkInterceptor添加缓存拦截器,不能使用.addInterceptor,也无需两者同时使用。

3.此方法无需服务器端任何 *** 作,适用于服务器端没有其他缓存策略,如果服务器端有自己的缓存策略代码应该做相应的修改,以适应服务器端。 

附上所有代码:

/** * 简单封装的Retroit初始化类 */public class initRetrofit { private static String baseUrl = "http://202.171.212.154:8080/hh/"; private static OkhttpClIEnt httpClIEnt; private static Retrofit retrofit; public static Retrofit initRetrofit() {  //缓存路径和大小  file httpCacheDirectory = new file(Environment.getExternalStorageDirectory(),"httpCache");  int cacheSize = 10 * 1024 * 1024;  Cache cache = new Cache(httpCacheDirectory,cacheSize);  //日志拦截器  httpLoggingInterceptor interceptor = new httpLoggingInterceptor();  interceptor.setLevel(httpLoggingInterceptor.Level.BODY);  httpClIEnt = new OkhttpClIEnt.Builder()    .connectTimeout(10,TimeUnit.SECONDS)//写入超时    .addInterceptor(interceptor)//添加日志拦截器    .addNetworkInterceptor(REWRITE_CACHE_CONTRol_INTERCEPTOR)//添加缓存拦截器    .cache(cache)//把缓存添加进来    .build();  retrofit = new Retrofit.Builder()    .baseUrl(baseUrl)    .clIEnt(httpClIEnt)    .addConverterFactory(GsonConverterFactory.create())    .build();  return retrofit; } public static RetrofitAPI getService() {  return initRetrofit().create(RetrofitAPI.class); }// //缓存拦截器,不同接口不同缓存// static Interceptor REWRITE_CACHE_CONTRol_INTERCEPTOR = new Interceptor() {//  @OverrIDe//  public Response intercept(Chain chain) throws IOException {////   Request request = chain.request();//   Response response = chain.proceed(request);////   if (NetworkUtil.getInstance().isConnected()) {//    String cacheControl =request.cacheControl().toString();//    return response.newBuilder()//      .removeheader("Pragma")//清除头信息,因为服务器如果不支持,会返回一些干扰信息,不清除下面无法生效//      .header("Cache-Control",cacheControl)//      .build();//   }//   return response;//  }// }; //缓存拦截器,统一缓存60s static Interceptor REWRITE_CACHE_CONTRol_INTERCEPTOR = new Interceptor() {  @OverrIDe  public Response intercept(Chain chain) throws IOException {   Request request = chain.request();   Response response = chain.proceed(request);   if (NetworkUtil.getInstance().isConnected()) {    int maxAge = 60*60*24*2;//缓存失效时间,单位为秒    return response.newBuilder()      .removeheader("Pragma")//清除头信息,因为服务器如果不支持,会返回一些干扰信息,不清除下面无法生效      .header("Cache-Control",max-age=" + maxAge)      .build();   }   return response;  } };}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。

总结

以上是内存溢出为你收集整理的Android中okhttp3.4.1+retrofit2.1.0实现离线缓存全部内容,希望文章能够帮你解决Android中okhttp3.4.1+retrofit2.1.0实现离线缓存所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1147954.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存