当客户端和服务端不能达成一致的协议,不能要求服务端按照客户端的意愿进行开发
缓存之拦截器
class CacheInterceptor implements Interceptor{
@Override
public Response intercept(Chain chain) throws IOException {
// 每个拦截器都必须至少调用chain.proceed(request)一次,它实现了Http请求的发起以及从服务端获取响应
Response originResponse = chain.proceed(chain.request());
//设置缓存时间为60秒,并移除了pragma消息头,移除它的原因是因为pragma也是控制缓存的一个消息头属性
return originResponse.newBuilder().removeHeader("pragma")
.header("Cache-Control","max-age=60").build();
}
}
拦截器是在OkHttpClient.Builder当中添加的,这样会导致图片的缓存和新闻列表的缓存时间是一样的,这样是不合理的。官方建议用CacheControl这个类
主要在两个地方配置,一个是构造OkHttpClient时,还有一个是在构造Request时
在OkHttpClient构造时设置缓存路径
OkHttpClient在封装的时候可以设置很多属性,包括cache,配置cache后OkHttp请求的数据就会缓存到该路径下,当手机没有联网时,就直接从缓存中获取。
Response的消息有两种类型,CacheResponse和NetworkResponse。CacheResponse代表从缓存取到的消息,NetworkResponse代表直接从服务端返回的消息
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(5, TimeUnit.SECONDS)
.cache(new Cache(new File(this.getExternalCacheDir(), "okhttpcache"), 10 * 1024 * 1024))
.build();
构造Request时配置缓存策略
配置CacheControl,它是针对Request的,它可以针对每个请求设置不同的缓存策略。
构造CacheControl
CacheControl cc = new CacheControl.Builder()
//不使用缓存,但是会保存缓存数据
//.noCache()
//不使用缓存,同时也不保存缓存数据
// .noStore()
//只使用缓存,(如果我们要加载的数据本身就是本地数据时,可以使用这个,不过目前尚未发现使用场景)
//.onlyIfCached()
//超时时间为当前时间加上10秒
.minFresh(10,TimeUnit.SECONDS)
//设置超时时间为10s
.maxAge(10,TimeUnit.SECONDS)
//超时之外的超时时间为10s
.maxStale(5,TimeUnit.SECONDS)
.build();
Request request = new Request.Builder()
.url("http://publicobject.com/helloworld.txt")
.cacheControl(cc)
.build();
使用CacheControl中的常量
// public static final CacheControl FORCE_NETWORK = new Builder().noCache().build();
// public static final CacheControl FORCE_CACHE = new Builder()
.onlyIfCached()
.maxStale(Integer.MAX_VALUE, TimeUnit.SECONDS)
.build();
Request request = new Request.Builder()
//强制使用网络
//.cacheControl(CacheControl.FORCE_NETWORK)
//强制使用缓存
.cacheControl(CacheControl.FORCE_CACHE)
.url("http://publicobject.com/helloworld.txt")
.build();