Retrofit2.0+okhttp3缓存策略

 

96 Aron1001 关注

2017.04.09 17:59* 字数 445 阅读 590评论 1喜欢 0

概述

  • 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();

缓存策略交互 — 最长使用期限和最长过期时间

为了帮助确保将最新鲜的内容返回给客户端应用程序,客户端缓存策略和服务器重新验证要求的交互始终会造成最保守的缓存策略。 本主题中的所有示例阐明针对在 1 月 1 日缓存、1 月 4 日过期的资源的缓存策略。

在以下示例中,结合使用了最长过期时间值 (maxStale) 与最长使用时间 (maxAge):

  • 如果缓存策略设置 maxAge = 5 天,且未指定 maxStale 值,根据 maxAge 值,此内容在 1 月 6 日前可用。 但是,根据服务器的重新验证要求,内容会在 1 月 4 日过期。 因为内容过期日期更保守(更早),所以它优先于 maxAge 策略。 因此,即使尚未达到最长使用时间,此内容在 1 月 4 日便会过期,并且必须进行重新验证。

  • 如果缓存策略设置 maxAge = 5 天,maxStale = 3 天,根据 maxAge 值,此内容在 1 月 6 日前可用。 根据 maxStale 值,此内容在 1 月 7 日前可用。 因此,会在 1 月 6 日重新验证此内容。

  • 如果缓存策略设置 maxAge = 5 天,maxStale = 1 天,根据 maxAge 值,此内容在 1 月 6 日前可用。 根据 maxStale 值,此内容在 1 月 5 日前可用。 因此,会在 1 月 5 日重新验证此内容。

当内容的最长使用时间小于过期日期时,更保守的缓存行为占据优先级,且最长过期时间值不会有任何效果。 以下示例阐明了在内容过期之前到达最长使用时间 (maxAge) 时设置最长过期时间 (maxStale) 值的效果:

  • 如果缓存策略设置 maxAge = 1 天,且未指定 maxStale 值,即使内容尚未过期,也会在 1 月 2 日重新验证此内容。

  • 如果设缓存策略设置 maxAge = 1 天,maxStale = 3 天,会在 1 月 2 日重新验证此内容以强制实施更保守的策略设置。

  • 如果缓存策略设置 maxAge = 1 天,maxStale = 1 天,会在 1 月 2 日重新验证此内容。

猜你喜欢

转载自blog.csdn.net/xinzhou201/article/details/82154517