Okhttp3结合Retrofit2 实现缓存

简介

Retrofit本身并没有缓存。OkHttp是由Square发布的一个HTTP client,它支持高速缓存服务器响应的语义。如果服务器的响应具有Cache-Control头,例如,它将被缓存,以便随后的请求可以从高速缓存中的获得之前的资源。

因此,设备处于断网情况下,Retrofit与Okhttp配合可以实现缓存。

Okhttp缓存设计和浏览器设计一样,是用来提升用户体验以及降低浏览器负荷的。项目实际开发过程中,我们使用到的无非两种情景:

1.无论是否有网,一定时间段内都是先读缓存,不同的接口根据自己的实时性可以自定义这个时间段长短

2.没有网络的时候可以读取缓存,有网络时读取在线的最新数据

代码设计来源于实际需求,因而自然而然要求封装的代码对外支持两种缓存策略的选择。

RxjavaRetrofitDemo

1.基本知识

设置缓存路径

//设置缓存路径 内置存储

File httpCacheDirectory =new File(context.getCacheDir(),"responses");

//外部存储

File httpCacheDirectory =new File(context.getExternalCacheDir(),"responses");

设置缓存大小

int cacheSize =DEFAULT_HTTP_CACHE_SIZE;  //设置缓存10M

使用httpCacheDirectory和cacheSize生成对象Cache,用于Okhttp的cache入参

Cache cache =new Cache(httpCacheDirectory,cacheSize);

OkHttpClient.Builder builder =newOkHttpClient.Builder();

builder.cache(cache);

为每个接口设置缓存时间段,max-age 的单位是秒, 表示缓存时长

Okhttp3结合Retrofit2 实现缓存_第1张图片
每个接口设置缓存时间段

设置Interceptor

builder.addInterceptor(baseInterceptor);

设置NetworkInterceptor

builder.addNetworkInterceptor(rewriteCacheControlInterceptor);

2.两种缓存策略

第一种:无论有网没网,一定时间段内都去读取缓存

只需单独设置NetworkInterceptor即可,重写Interceptor的intercept方法,代码中实现如果服务端设置相应的缓存策略那么遵从服务端的不做修改,否则判断对应接口请求时是否设置cacheControl,如果请求接口中未设置cacheControl,则统一设置为一分钟

Okhttp3结合Retrofit2 实现缓存_第2张图片
intercept中关键代码

上层调用代码

OkHttpClient.Builder builder =new OkHttpClient.Builder();

builder.addNetworkInterceptor(rewriteCacheControlInterceptor);

第二种:没网络的情况下读取缓存,有网络时读取最新数据

在设置addNetworkInterceptor的基础上,需要设置addInterceptor,实际上就是覆盖重写一个Interceptor,代码中判断在没有网络时,通过劫持request,从而达到目的

Okhttp3结合Retrofit2 实现缓存_第3张图片
baseInterceptor关键代码

上层调用代码,如果想实现第二种缓存策略,则必须两个拦截器都加

OkHttpClient.Builder builder =new OkHttpClient.Builder();

builder.addInterceptor(baseInterceptor);

builder.addNetworkInterceptor(rewriteCacheControlInterceptor);

3.对于两种缓存策略的封装

Okhttp3结合Retrofit2 实现缓存_第4张图片
两种缓存策略封装

4.与Retrofit关联

Okhttp3结合Retrofit2 实现缓存_第5张图片
Okhttp与Retrofit关联

5.Interceptor和NetworkInterceptor有什么区别

可以看下图:

Okhttp3结合Retrofit2 实现缓存_第6张图片
Interceptor和NetworkInterceptor的区别

所以如果只是想实现第一种缓存策略,只需设置networkInterceptor即可,如果想要离线时只读取缓存,则需设置两种拦截器

你可能感兴趣的:(Okhttp3结合Retrofit2 实现缓存)