CacheInterceptor

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_21727627/article/details/79031955

 要想清楚的了解可以三个类去了解

1.从 InternalCache 缓存类开始 然后只是一个接口 OkHttpClient 已经用Cache类 实现了

使用:

File externalStorageDirectory = Environment.getExternalStorageDirectory();
File cache = new File(externalStorageDirectory, "cache");
okHttpClient = new OkHttpClient.Builder()
      .cache(new Cache(cache, 1024 * 1024))
      .build();
Cache 类都做了什么呢:

Cache(File directory, long maxSize, FileSystem fileSystem) {
  this.cache = DiskLruCache.create(fileSystem, directory, VERSION, ENTRY_COUNT, maxSize);
}

看到DiskLruCache 是不是很熟,就是使用这个对response 进行缓存的,并在里面用静态代理模式实现 InternalCache接口 .

2.CacheStrategy 缓存策略类 get()方法:

public CacheStrategy get() {
  CacheStrategy candidate = getCandidate();

  if (candidate.networkRequest != null && request.cacheControl().onlyIfCached()) {
    // We're forbidden from using the network and the cache is insufficient.
    return new CacheStrategy(null, null); //必须从缓存中读取
  }

  return candidate;
}
逻辑都在getCandidate()方法中作用:判断request 是否要网络请求,计算 response cache 是否过期,上面都不返回判断是否添加请求头再次做网络请求.

 3.最后就是自身intercept方法了:

@Override public Response intercept(Chain chain) throws IOException {
    Response cacheCandidate = cache != null
        ? cache.get(chain.request())  // url为 key取出缓存
        : 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);
    }
	//可能需要网络请求或者cacheResponse 没有过期
    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())         //不能网络请求和从缓存中读取,将返回504响应吗
          .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.
    if (networkRequest == null) {     //返回有四种 1都为null(上面已经处理了),2.都为notnull 3.一个为Null 另一个为notnull
                                           4.跟3反过来   
   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 (networkResponse.code() == HTTP_NOT_MODIFIED) { //304 客户端已缓存标记
        Response response = cacheResponse.newBuilder()
            .headers(combine(cacheResponse.headers(), networkResponse.headers())) //合并响应头 因为放在 Arraylist 
中,重复会覆盖掉
            .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();

    if (cache != null) {
    //判断是否有响应体 和是否能缓存
      if (HttpHeaders.hasBody(response) && CacheStrategy.isCacheable(response, networkRequest)) {
        // Offer this request to the cache.
        CacheRequest cacheRequest = cache.put(response);   //放入缓存中
        return cacheWritingResponse(cacheRequest, response); 
      }

      if (HttpMethod.invalidatesCache(networkRequest.method())) {  //默认支持get 不是get 将从缓存中移除
        try {
          cache.remove(networkRequest);
        } catch (IOException ignored) {
          // The cache cannot be written.
        }
      }
    }

    return response;
  }
.最后就是这样吧,不清楚Socket,ConnectionInterceptor和CallServerInterceptor很难讲清楚 ,

ConnectionInterceptor 大概作用是:创建或者获取RealConnection,HttpCodec 和进行三次握手.

CallServerInterceptor :数据传输

ps:菜鸟一枚,不对望指正.

猜你喜欢

转载自blog.csdn.net/qq_21727627/article/details/79031955