美文网首页前端开发技术
Retrofit2.0+okhttp3缓存策略

Retrofit2.0+okhttp3缓存策略

作者: Aron1001 | 来源:发表于2017-04-09 17:59 被阅读441次

    概述

    • Retrofit本身是没有缓存的,如果想设置缓存功能,需要在http client层知道HTTP的语义。
    • okhttp是square公司发布的一个HTTP client,它支持高速缓存服务器响应的语义。
    • 使用场景:提高用户体验,降低服务器的负荷。无网络的条件下,读取缓存;有网条件下,对非实时性的数据可以在规定的时间里读取缓存,例如设置时间为60s,实时性的数据还是要每次都获取最新数据。

    封装Retrofit管理类

     public class RetrofitManger {
          private static RetrofitManger mInstance;
          public static boolean isDebug = false;
    
        public static synchronized RetrofitManger getInstance() {
        if (mInstance == null)
            mInstance = new RetrofitManger();
        return mInstance;
        }
    
        public void deBug(boolean isDebug) {
        this.isDebug = isDebug;
        }
    
        // create retrofit singleton
        private Retrofit createApiClient(String baseUrl) {
            return new Retrofit.Builder()
                .baseUrl(baseUrl)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .client(createOkHttpClient(isDebug))
                .build();
          }
    
        // create okHttpClient singleton
        OkHttpClient createOkHttpClient(boolean debug) {
        //设置缓存100M
            Cache cache = new Cache(new File(MainApplication.getContext().getCacheDir(),"httpCache"),1024 * 1024 * 100);
            return new OkHttpClient.Builder()
                .cache(cache)
                .addNetworkInterceptor(new HttpCacheInterceptor())
                .addInterceptor(
                        new HttpLoggingInterceptor().setLevel(
                                debug ? HttpLoggingInterceptor.Level.BODY : HttpLoggingInterceptor.Level.NONE))
                .build();
          }
    }
    

    HttpCacheInterceptor类

    public class HttpCacheInterceptor implements Interceptor {
    
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        if (!NetWorkHelper.isNetConnected(MainApplication.getContext())) {
            request = request.newBuilder()
                    .cacheControl(CacheControl.FORCE_CACHE)
                    .build();
        }
    
        Response response = chain.proceed(request);
    
        if (NetWorkHelper.isNetConnected(MainApplication.getContext())) {
            int maxAge = 60 * 60; // read from cache for 1 minute
            response.newBuilder()
                    .removeHeader("Pragma")
                    .header("Cache-Control", "public, max-age=" + maxAge)
                    .build();
        } else {
            int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale
            response.newBuilder()
                    .removeHeader("Pragma")
                    .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
                    .build();
        }
        return response;
      }
    }
    

    有网络的情况下设置max-age=60 x 60,即1分钟;没有网络的情况下设置max-stale=60 x 60 x 24 x 28,即4周。

    okhttp3 中Cache类包含的缓存策略

    noCache :不使用缓存,全部走网络
    noStore : 不使用缓存,也不存储缓存
    onlyIfCached : 只使用缓存
    maxAge :设置最大失效时间,失效则不使用

    maxStale :设置最大失效时间,失效则不使用
    minFresh :设置最小有效时间,失效则不使用
    FORCE_NETWORK : 强制走网络
    FORCE_CACHE :强制走缓存

    单个接口设置缓存

    上面介绍的都是统一设置缓存,Retrofit还可以为单个接口设置缓存。
    配置单个请求的@Headers,设置此请求的缓存策略不影响其他请求的缓存策略,不设置则没有缓存。

    // 设置单个请求的缓存时间
    @Headers("Cache-Control: max-age=640000")
    @GET("user/list")
    Call<List<javaBean>> getList();

    读取单个接口的@Headers配置

    String cacheControl = request.cacheControl().toString();
    response.newBuilder()
    .header("Cache-Control", cacheControl)
    .removeHeader("Pragma")
    .build();

    相关文章

      网友评论

      • Jafir:楼主 有没有亲自测试过这个方法呢?想跟你交流交流
        artzok:60 * 60 是一分钟嘛

      本文标题:Retrofit2.0+okhttp3缓存策略

      本文链接:https://www.haomeiwen.com/subject/jpdtattx.html