美文网首页
okhttp缓存策略

okhttp缓存策略

作者: 六比七大 | 来源:发表于2021-04-29 11:55 被阅读0次

/** Returns a strategy to use assuming the request can use the network. */
private CacheStrategy getCandidate() {
// No cached response.
//1、没设置磁盘缓存
if (cacheResponse == null) {
return new CacheStrategy(request, null);
}

  // Drop the cached response if it's missing a required handshake.
  //2 如果时TLS握手信息丢失,直接进行网络请求
  if (request.isHttps() && cacheResponse.handshake() == null) {
    return new CacheStrategy(request, null);
  }

  // If this response shouldn't have been stored, it should never be used
  // as a response source. This check should be redundant as long as the
  // persistence store is well-behaved and the rules are constant.
  // 3 缓存和请求都设置了no-store(重要信息,禁止缓存)
  if (!isCacheable(cacheResponse, request)) {
    return new CacheStrategy(request, null);
  }

  //获取请求的cachecontrol
  CacheControl requestCaching = request.cacheControl();
  //4、1请求的cacheControl为noCache
  //4、2请求头设置了If-Modified-Since或者If-None-Match
  if (requestCaching.noCache() || hasConditions(request)) {
    return new CacheStrategy(request, null);
  }
    
    //走到这里说明缓存可用

  //获取缓存的cacheControl
  CacheControl responseCaching = cacheResponse.cacheControl();
  if (responseCaching.immutable()) {
    return new CacheStrategy(null, cacheResponse);
  }
  //该response已经缓存的时长
  long ageMillis = cacheResponseAge();
  //该response可以缓存的时长
  long freshMillis = computeFreshnessLifetime();

  if (requestCaching.maxAgeSeconds() != -1) {
    freshMillis = Math.min(freshMillis, SECONDS.toMillis(requestCaching.maxAgeSeconds()));
  }

  long minFreshMillis = 0;
  if (requestCaching.minFreshSeconds() != -1) {
    minFreshMillis = SECONDS.toMillis(requestCaching.minFreshSeconds());
  }

  long maxStaleMillis = 0;
  if (!responseCaching.mustRevalidate() && requestCaching.maxStaleSeconds() != -1) {
    maxStaleMillis = SECONDS.toMillis(requestCaching.maxStaleSeconds());
  }
  //5 判断缓存是否过期
  if (!responseCaching.noCache() && ageMillis + minFreshMillis < freshMillis + maxStaleMillis) {
    Response.Builder builder = cacheResponse.newBuilder();
    if (ageMillis + minFreshMillis >= freshMillis) {
      builder.addHeader("Warning", "110 HttpURLConnection \"Response is stale\"");
    }
    long oneDayMillis = 24 * 60 * 60 * 1000L;
    if (ageMillis > oneDayMillis && isFreshnessLifetimeHeuristic()) {
      builder.addHeader("Warning", "113 HttpURLConnection \"Heuristic expiration\"");
    }
    // 5.1 缓存没过期直接使用
    return new CacheStrategy(null, builder.build());
  }

  // Find a condition to add to the request. If the condition is satisfied, the response body
  // will not be transmitted.
  //5.2 缓存已经过期了,判断是否设置了etag和last-Modified标志
  String conditionName;
  String conditionValue;
  if (etag != null) {
    conditionName = "If-None-Match";
    conditionValue = etag;
  } else if (lastModified != null) {
    conditionName = "If-Modified-Since";
    conditionValue = lastModifiedString;
  } else if (servedDate != null) {
    conditionName = "If-Modified-Since";
    conditionValue = servedDateString;
  } else {
    return new CacheStrategy(request, null); // No condition! Make a regular request.
  }
 //设置了etag或者last-modified则添加头部字段,构造请求,交给服务器判断缓存是否可用
  Headers.Builder conditionalRequestHeaders = request.headers().newBuilder();
  Internal.instance.addLenient(conditionalRequestHeaders, conditionName, conditionValue);

  Request conditionalRequest = request.newBuilder()
      .headers(conditionalRequestHeaders.build())
      .build();
  return new CacheStrategy(conditionalRequest, cacheResponse);
}


1、netrequest和cacheresponse 都为空,返回504结束
2、netrequest为空 cacheResponse不空,直接使用强制缓存
3、都不为空表示使用比较缓存,304更新缓存后使用,200缓存失效使用响应
4、netrequest不为空,cacheResponse为空,使用网络并缓存

相关文章

网友评论

      本文标题:okhttp缓存策略

      本文链接:https://www.haomeiwen.com/subject/jqnvrltx.html