OKHttp原码分析(四)之getResponseWithInterceptorChain方法

一,概述

OKHttp原码分析(一)最后讲到无论是同步请求还是异步请求都殊途同归到了RealCall的getResponseWithInterceptorChain方法。这篇blog主要讲解RealCall的getResponseWithInterceptorChain方法。

二,getResponseWithInterceptorChain方法源码

  private Response getResponseWithInterceptorChain() throws IOException {
    // Build a full stack of interceptors.
    List<Interceptor> interceptors = new ArrayList<>();
    interceptors.addAll(client.interceptors());
    interceptors.add(retryAndFollowUpInterceptor);
    interceptors.add(new BridgeInterceptor(client.cookieJar()));
    interceptors.add(new CacheInterceptor(client.internalCache()));
    interceptors.add(new ConnectInterceptor(client));
    if (!retryAndFollowUpInterceptor.isForWebSocket()) {
      interceptors.addAll(client.networkInterceptors());
    }
    interceptors.add(new CallServerInterceptor(
        retryAndFollowUpInterceptor.isForWebSocket()));

    Interceptor.Chain chain = new RealInterceptorChain(
        interceptors, null, null, null, 0, originalRequest);
    return chain.proceed(originalRequest);
  }

注意点:

  1. 方法的返回值是Response 。这个就是网络请求的目的,得到的数据都封装在Response 对象中。
  2. 拦截器的使用。在方法的第一行中就创建了interceptors 集合,然后紧接着放进去很多拦截器对象。
  3. RealInterceptorChain类的proceed方法。getResponseWithInterceptorChain方法的最后创建了RealInterceptorChain对象,并调用proceed方法。Response 对象就有由RealInterceptorChain类的proceed方法返回的。

下面看RealInterceptorChain类的proceed方法的原码。

三,RealInterceptorChain类的proceed方法的原码

  public Response proceed(Request request, StreamAllocation streamAllocation, HttpStream httpStream,Connection connection) throws IOException {
    if (index >= interceptors.size()) throw new AssertionError();
    calls++;
    // If we already have a stream, confirm that this is the only call to chain.proceed().
    if (this.httpStream != null && calls > 1) {
      throw new IllegalStateException("network interceptor " + interceptors.get(index - 1)
          + " must call proceed() exactly once");
    }

    // Call the next interceptor in the chain.
    RealInterceptorChain next = new RealInterceptorChain(
        interceptors, streamAllocation, httpStream, connection, index + 1, request);
    Interceptor interceptor = interceptors.get(index);
    Response response = interceptor.intercept(next);
    return response;
  }

分析:

  1. 注意index和calls两个整形字段,如果index大于等于集合的长度,calls就++,calls大于1就会抛出异常。所以在正常情况下index是小于集合的长度的。
  2. index的初始化在RealInterceptorChain的构造方法中,也就是在getResponseWithInterceptorChain放中创建RealInterceptorChain对象时被初始化的。我们发现初始化值是0。
  3. 在该方法末尾再次创建RealInterceptorChain对象,此时index值是1。然后得到拦截器对象,调用拦截器的intercept方法,并把index等于1的RealInterceptorChain对象传递过去。
  4. interceptor的intercept方法的返回值是Response 。注意Response 是从这儿来的。

猜你喜欢

转载自blog.csdn.net/fightingxia/article/details/71254375