缓存拦截器就是处理缓存数据,这个思路上不复杂,如果你们配置使用缓存数据,就会根据缓存策略判断是否能使用缓存的数据,如果可以就取缓存的数据,否则,则去请求网络。
@Override public Response intercept(Chain chain) throws IOException {
/** 首先判断缓存对象是否为null,非空就获取缓存对象,否则null,且给Response 赋值
*cache对象是谁, InternalCache cache; 由当前缓存拦截器构造的时候传入。*InternalCache 是个接口,所以去看实现类,但是实现类没有,但是在okhttp3.Cache里找
*到了InternalCache 的内部类实例,同时还重写相应的方法。get put remove update等方法。
下面细讲
*/
Response cacheCandidate = cache != null ? cache.get(chain.request()) : null;
long now = System.currentTimeMillis();
//CacheStrategy 缓存策略对象,工厂模式,最后get()获取
CacheStrategy strategy = new CacheStrategy.Factory(now, chain.request(), cacheCandidate).get();
Request networkRequest = strategy.networkRequest;
Response cacheResponse = strategy.cacheResponse;
if (cache != null) {
cache.trackResponse(strategy);
}
//缓存对象不为空,但是缓存的响应对象null,关闭缓存
if (cacheCandidate != null && cacheResponse == null) {
closeQuietly(cacheCandidate.body()); // The cache candidate wasn't applicable. Close it.
}
// If we're forbidden from using the network and the cache is insufficient, fail.
// 网络请求对象null 缓存对象null 直接返回504 服务器错误
if (networkRequest == null && cacheResponse == null) {
return new Response.Builder()
.request(chain.request())
.protocol(Protocol.HTTP_1_1)
.code(504)
.message("Unsatisfiable Request (only-if-cached)")
.body(Util.EMPTY_RESPONSE)
.sentRequestAtMillis(-1L)
.receivedResponseAtMillis(System.currentTimeMillis())
.build();
}
// If we don't need the network, we're done.
// 请求对象为null,返回缓存的对象,该对象是null的body对象,
//stripBody方法去除了body
if (networkRequest == null) {
return cacheResponse.newBuilder()
.cacheResponse(stripBody(cacheResponse))
.build();
}
Response networkResponse = null;
try {
// 执行下一个拦截器
networkResponse = chain.proceed(networkRequest);
} finally {
// If we're crashing on I/O or otherwise, don't leak the cache body.
if (networkResponse == null && cacheCandidate != null) {
// 关闭缓存
closeQuietly(cacheCandidate.body());
}
}
// If we have a cache response too, then we're doing a conditional get.
// 如果缓存对象不为空,且返回403-重定向无修改数据,合并缓存的header和网络的header
//
if (cacheResponse != null) {
if (networkResponse.code() == HTTP_NOT_MODIFIED) {
Response response = cacheResponse.newBuilder()
.headers(combine(cacheResponse.headers(), networkResponse.headers()))
.sentRequestAtMillis(networkResponse.sentRequestAtMillis())
.receivedResponseAtMillis(networkResponse.receivedResponseAtMillis())
.cacheResponse(stripBody(cacheResponse))
.networkResponse(stripBody(networkResponse))
.build();
networkResponse.body().close();
// Update the cache after combining headers but before stripping the
// Content-Encoding header (as performed by initContentStream()).
cache.trackConditionalCacheHit();
//更新缓存数据
cache.update(cacheResponse, response);
return response;
} else {
closeQuietly(cacheResponse.body());
}
}
Response response = networkResponse.newBuilder()
.cacheResponse(stripBody(cacheResponse))
.networkResponse(stripBody(networkResponse))
.build();
// 判断是否有body
if (HttpHeaders.hasBody(response)) {
// 判断是否请求方法合法,因为缓存只处理GET请求,不合法从缓存对象移除
CacheRequest cacheRequest = maybeCache(response, networkResponse.request(), cache);
// 写入响应对象到缓存
response = cacheWritingResponse(cacheRequest, response);
}
return response;
}