OkHttp3源码详解之HTTP重定向&缓存的处理(二),Android面试题及解析

: null;

long now = System.currentTimeMillis();
//构造缓存策略,然后进行策略判断
cacheStrategy = new CacheStrategy.Factory(now, request, cacheCandidate).get();
//策略判定后的网络请求和缓存响应
networkRequest = cacheStrategy.networkRequest;
cacheResponse = cacheStrategy.cacheResponse;

if (responseCache != null) {
//使用缓存响应的话,记录一下使用记录
responseCache.trackResponse(cacheStrategy);
}

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) {
//强制使用缓存,又找不到缓存,就报不合理请求响应了
userResponse = new Response.Builder()
.request(userRequest)
.priorResponse(stripBody(priorResponse))
.protocol(Protocol.HTTP_1_1)
.code(504)
.message(“Unsatisfiable Request (only-if-cached)”)
.body(EMPTY_BODY)
.build();
return;
}

//上面情况处理之后,就是使用缓存返回,还是网络请求的情况了

// If we don’t need the network, we’re done.
if (networkRequest == null) {
//使用缓存返回响应
userResponse = cacheResponse.newBuilder()
.request(userRequest)
.priorResponse(stripBody(priorResponse))
.cacheResponse(stripBody(cacheResponse))
.build();
userResponse = unzip(userResponse);
return;
}

//使用网络请求
//下面就是网络请求流程了,略

}
}

接下来我们分析

  1. Cache是如何获取缓存的。
  2. 缓存策略是如何判断的。
Cache获取缓存

从Cache的get方法开始。它按以下步骤进行。

  1. 计算request对应的key值,md5加密请求url得到。
  2. 根据key值去DiskLruCache查找是否存在缓存内容。
  3. 存在缓存的话,创建缓存Entry实体。ENTRY_METADATA代表响应头信息,ENTRY_BODY代表响应体信息。
  4. 然后根据缓存Entry实体得到响应,其中包含了缓存的响应头和响应体信息。
  5. 匹配这个缓存响应和请求的信息是否匹配,不匹配的话要关闭资源,匹配的话返回。

public final class Cache implements Closeable, Flushable {
//获取缓存
Response get(Request request) {
//计算请求对应的key
String key = urlToKey(request);
DiskLruCache.Snapshot snapshot;
Entry entry;
try {
//这里从DiskLruCache中读取缓存信息
snapshot = cache.get(key);
if (snapshot == null) {
return null;
}
} catch (IOException e) {
// Give up because the cache cannot be read.
return null;
}

try {
//这里读取缓存的响应头信息
entry = new Entry(snapshot.getSource(ENTRY_METADATA));
} catch (IOException e) {
Util.closeQuietly(snapshot);
return null;
}
//然后得到响应信息,包含了缓存响应头和响应体信息
Response response = entry.response(snapshot);
//判断缓存响应和请求是否匹配,匹配url,method,和其他响应头信息
if (!entry.matches(request, response)) {
//不匹配的话,关闭响应体
Util.closeQuietly(response.body());
return null;
}

//返回缓存响应
return response;
}

//这里md5加密url得到key值
private static String urlToKey(Request request) {
return Util.md5Hex(request.url().toString());
}

}

如果存在缓存的话,在指定的缓存目录中,会有两个文件“.0”和“.1”,分别存储某个请求缓存的响应头和响应体信息。(“****”是url的md5加密值)对应的ENTRY_METADATA响应头和ENTRY_BODY响应体。缓存的读取其实是由DiskLruCache来读取的,DiskLruCache是支持Lru(最近最少访问)规则的用于磁盘存储的类,对应LruCache内存存储。它在存储的内容超过指定值之后,就会根据最近最少访问的规则,把最近最少访问的数据移除,以达到总大小不超过限制的目的。

接下来我们分析CacheStrategy缓存策略是怎么判定的。

CacheStrategy缓存策略

直接看CacheStrategy的get方法。缓存策略是由请求和缓存响应共同决定的。

  1. 如果缓存响应为空,则缓存策略为不使用缓存。
  2. 如果请求是https但是缓存响应没有握手信息,同上不使用缓存。
  3. 如果请求和缓存响应都是不可缓存的,同上不使用缓存。
  4. 如果请求是noCache,并且又包含If-Modified-Since或If-None-Match,同上不使用缓存。
  5. 然后计算请求有效时间是否符合响应的过期时间,如果响应在有效范围内,则缓存策略
  • 26
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值