OkHttp3(九)--RealInterceptorChain

2019-01-28  本文已影响0人  azu_test

RealInterceptorChain

RealInterceptorChain关键代码

public final class RealInterceptorChain implements Interceptor.Chain {
  //所有的拦截器都存储在这个链表里
  private final List<Interceptor> interceptors;
  //这个非常重要,将会单独解读处理
  private final StreamAllocation streamAllocation;
  //这个非常重要,将会单独解读处理
  private final HttpCodec httpCodec;
  //这个非常重要,将会单独解读处理
  private final RealConnection connection;
  private final int index;
  private final Request request;
  private final Call call;
  private final EventListener eventListener;
  private final int connectTimeout;
  private final int readTimeout;
  private final int writeTimeout;
  private int calls;
  //构造方法
  public RealInterceptorChain(List<Interceptor> interceptors, StreamAllocation streamAllocation,
      HttpCodec httpCodec, RealConnection connection, int index, Request request, Call call,
      EventListener eventListener, int connectTimeout, int readTimeout, int writeTimeout) {
    this.interceptors = interceptors;
    this.connection = connection;
    this.streamAllocation = streamAllocation;
    this.httpCodec = httpCodec;
    this.index = index;
    this.request = request;
    this.call = call;
    this.eventListener = eventListener;
    this.connectTimeout = connectTimeout;
    this.readTimeout = readTimeout;
    this.writeTimeout = writeTimeout;
  }
  //执行继续拦截操作
  @Override public Response proceed(Request request) throws IOException {
    return proceed(request, streamAllocation, httpCodec, connection);
  }
  //执行继续拦截操作
  public Response proceed(Request request, StreamAllocation streamAllocation, HttpCodec httpCodec,
      RealConnection connection) throws IOException {
    if (index >= interceptors.size()) throw new AssertionError();

    calls++;

    // If we already have a stream, confirm that the incoming request will use it.
    if (this.httpCodec != null && !this.connection.supportsUrl(request.url())) {
      throw new IllegalStateException("network interceptor " + interceptors.get(index - 1)
          + " must retain the same host and port");
    }

    // If we already have a stream, confirm that this is the only call to chain.proceed().
    if (this.httpCodec != null && calls > 1) {
      throw new IllegalStateException("network interceptor " + interceptors.get(index - 1)
          + " must call proceed() exactly once");
    }

    //创建新的实例, 并将计数器+1
    RealInterceptorChain next = new RealInterceptorChain(interceptors, streamAllocation, httpCodec,
        connection, index + 1, request, call, eventListener, connectTimeout, readTimeout,
        writeTimeout);
    //取出下一个拦截器
    Interceptor interceptor = interceptors.get(index);
    //执行拦截器方法,拦截器中又会调用proceed()方法
    Response response = interceptor.intercept(next);
    // Confirm that the next interceptor made its required call to chain.proceed().
    if (httpCodec != null && index + 1 < interceptors.size() && next.calls != 1) {
      throw new IllegalStateException("network interceptor " + interceptor
          + " must call proceed() exactly once");
    }
    // Confirm that the intercepted response isn't null.
    if (response == null) {
      throw new NullPointerException("interceptor " + interceptor + " returned null");
    }
    if (response.body() == null) {
      throw new IllegalStateException(
          "interceptor " + interceptor + " returned a response with no body");
    }
    return response;
  }
}
  • 上面代码中有我们实例化的接口,但是里面有一些属性在我们开始进来前没有做赋值处理,给的是空值。
  • 通过调用继续拦截操作proceed()方法将调用拦截器的Interceptor.intercept()方法,然后这个方法内部会根据条件抛出异常、结果或者继续调用proceed()方法进行下一项拦截。
  • 拦截器的顺序RetryAndFollowUpInterceptor,BridgeInterceptor
    CacheInterceptorConnectInterceptorCallServerInterceptor
  • 还有一些属性对象我们目前不知为什么作用,例如:StreamAllocation,HttpCodec,RealConnection。我们将根据代码运行流程一步步来解析。

根据上文的方法调用和拦截器的顺序我们可知下面将执行RetryAndFollowUpInterceptor拦截器。

下篇入口:OkHttp3(十)--RetryAndFollowUpInterceptor

上一篇下一篇

猜你喜欢

热点阅读