okhttp 之RetryAndFollowUpInterceptor(处理重试) 拦截器分析

首先我们从这个借口开始

public interface Interceptor {
//需要实现的方法
Response intercept(Chain chain) throws IOException;
 //内部类
interface Chain {
Request request();

Response proceed(Request request) throws IOException;

/**
 * Returns the connection the request will be executed on. This is only available in the chains
 * of network interceptors; for application interceptors this is always null.
 */
@Nullable Connection connection();

Call call();
  //设置连击世界
int connectTimeoutMillis();

Chain withConnectTimeout(int timeout, TimeUnit unit);

int readTimeoutMillis();

Chain withReadTimeout(int timeout, TimeUnit unit);

int writeTimeoutMillis();

Chain withWriteTimeout(int timeout, TimeUnit unit);

}
}
RetryAndFollowUpInterceptor 这个拦截器 首先我们 从intercept 这方法开始分析

 @Override 
 public Response intercept(Chain chain) throws IOException {
  / /获取请求
Request request = chain.request();
 //实例化
RealInterceptorChain realChain = (RealInterceptorChain) chain;

Call call = realChain.call();
EventListener eventListener = realChain.eventListener();

StreamAllocation streamAllocation = new StreamAllocation(client.connectionPool(),
    createAddress(request.url()), call, eventListener, callStackTrace);
this.streamAllocation = streamAllocation;

int followUpCount = 0;
Response priorResponse = null;
while (true) {
 //一个死循环 去不断的重连网络
  if (canceled) {
    streamAllocation.release();
    throw new IOException("Canceled");
  }

  Response response;
  boolean releaseConnection = true;
  try {
 //传给下一级  可能会获得一个异常 
    response = realChain.proceed(request, streamAllocation, null, null);
    releaseConnection = false;
  } catch (RouteException e) {
    // The attempt to connect via a route failed. The request will not have been sent.
    //自己先处理  做一系列的判断 有协议异常 打断异常等等
    if (!recover(e.getLastConnectException(), streamAllocation, false, request)) {
      throw e.getLastConnectException();
    }
    releaseConnection = false;
    continue;
  } catch (IOException e) {
    // An attempt to communicate with a server failed. The request may have been sent.
    boolean requestSendStarted = !(e instanceof ConnectionShutdownException);
    if (!recover(e, streamAllocation, requestSendStarted, request)) throw e;
    releaseConnection = false;
    continue;
  } finally {
    // We're throwing an unchecked exception. Release any resources.
    if (releaseConnection) {
      streamAllocation.streamFailed(null);
      streamAllocation.release();
    }
  }

  // Attach the prior response if it exists. Such responses never have a body.

  if (priorResponse != null) {
    response = response.newBuilder()
        .priorResponse(priorResponse.newBuilder()
                .body(null)
                .build())
        .build();
  }
 //从下面的拦截器传过来的一个response 不过可能有重定向 返回码 307 就是重新请求一次
//followUpRequest() 对状态码进行一系列判断  然后返回一个新连接的请求
  Request followUp = followUpRequest(response, streamAllocation.route());

  if (followUp == null) {
    if (!forWebSocket) {
      streamAllocation.release();
    }
    return response;
  }

  closeQuietly(response.body());

  if (++followUpCount > MAX_FOLLOW_UPS) {
    streamAllocation.release();
    throw new ProtocolException("Too many follow-up requests: " + followUpCount);
  }

  if (followUp.body() instanceof UnrepeatableRequestBody) {
    streamAllocation.release();
    throw new HttpRetryException("Cannot retry streamed HTTP body", response.code());
  }

  if (!sameConnection(response, followUp.url())) {
    streamAllocation.release();
    streamAllocation = new StreamAllocation(client.connectionPool(),
        createAddress(followUp.url()), call, eventListener, callStackTrace);
    this.streamAllocation = streamAllocation;
  } else if (streamAllocation.codec() != null) {
    throw new IllegalStateException("Closing the body of " + response
        + " didn't close its backing stream. Bad interceptor?");
  }
  //我的的请求 就变成followUp 这个重试的请求
  request = followUp;
  priorResponse = response;
}

}

你可能感兴趣的:(okhttp 之RetryAndFollowUpInterceptor(处理重试) 拦截器分析)