您的位置:首页 > 理论基础 > 计算机网络

OKhttp源码解析---拦截器之CacheInterceptor

2016-11-02 17:16 337 查看
同样,我们来看它的intercept

public Response intercept(Chain chain) throws IOException {
Response cacheCandidate = cache != null
? cache.get(chain.request())
: null;

long now = System.currentTimeMillis();

CacheStrategy strategy = new CacheStrategy.Factory(now, chain.request(), cacheCandidate).get();
Request networkRequest = strategy.networkRequest;
Response cacheResponse = strategy.cacheResponse;

if (cache != null) {
cache.trackResponse(strategy);
}

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.
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(EMPTY_BODY)
.sentRequestAtMillis(-1L)
.receivedResponseAtMillis(System.currentTimeMillis())
.build();
}

// If we don't need the network, we're done.
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.
if (cacheResponse != null) {
if (validate(cacheResponse, networkResponse)) {
Response response = cacheResponse.newBuilder()
.headers(combine(cacheResponse.headers(), networkResponse.headers()))
.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();

if (HttpHeaders.hasBody(response)) {
CacheRequest cacheRequest = maybeCache(response, networkResponse.request(), cache);
response = cacheWritingResponse(cacheRequest, response);
}

return response;
}具体流程大概如下:
1、首先判断用户是否有设置cache,如果有的话,则从用户的cache中获取当前请求的缓存,用户可以通过如下方式设置cache

OkHttpClient mOkHttpClient = new OkHttpClient();
mOkHttpClient.newBuilder().cache(new Cache(new File("D:"),1024*1024));InternalCache是不能直接使用的,而Cache可以直接使用,它里面自己实现了InternalCache

2、然后根据前面是否有缓存已经当前请求构造一个CacheStrategy,它的networkRequest代表当前请求,cacheResponse代表当前缓存响应
3、如果networkRequest为空则说明不需要网络请求,直接返回当前缓存

4、调用 networkResponse = chain.proceed(networkRequest)处理当前请求

5、如果缓存不为空,调用validate进行验证,是否需要更新缓存

6、如果缓存为空,则保存当前缓存

这样缓存就处理完了,里面还有很多的缓存策略什么的就没去深究,接下来继续调用下一个拦截器ConnectInterceptor进行处理
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: