OkHTTP源码学习(一)请求发起

473 阅读13分钟

OkHTTP源码学习(一)请求发起

本篇主要分析一下一个网络请求在没有经过网络发出时okhttp是如何组实现同步和异步网络请求

本文借鉴地址,强烈推荐大家点击查看

流程图镇楼


请求demo

啥也不多说让我们来先用api来实现一个网络请求

    OkHttpClient okHttpClient = new OkHttpClient();

    final Request request = new Request.Builder().url("https://baidu.com").build();

    Call call = okHttpClient.newCall(request);

    call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {

                LogUtil.d(response.message());
            }
        });

接下来让我们从头挨个排着来看一遍他到底是怎么工作的

Request

先贴源码

public final class Request {
  final HttpUrl url;  请求路径
  final String method; 请求方法
  final Headers headers; 请求头部
  final RequestBody body; 请求体
  final Object tag;  不同网络请求的不同标识位


   public static class Builder {
    HttpUrl url;
    String method;
    Headers.Builder headers;
    RequestBody body;
    Object tag;

    public Builder() {
      this.method = "GET";  默认采用的GET方式
      this.headers = new Headers.Builder(); request的首部也是采用builder模式创建
    }

    Builder(Request request) {
      this.url = request.url;
      this.method = request.method;
      this.body = request.body;
      this.tag = request.tag;
      this.headers = request.headers.newBuilder();
    }


    public Request build() {
      if (url == null) throw new IllegalStateException("url == null");
      return new Request(this);
    }

这里我们可以看到Request类才用建造者模式,其按照http的请求协议做了分门别类的实现,因此我们便可以在其默认的配置中通过重写不同的HeadersRequestBody等等配置来实现不同的http请求体。这最基本的请求,但是我们上传表单和文件的时候该怎么办,莫慌okhttp已经帮我们以Request父类实现了不同的子类去实现,如FormBody (表单提交的)和 MultipartBody(文件上传)等详见源码这里不做解释

OkHttpClient

public class OkHttpClient implements Cloneable, Call.Factory, WebSocket.Factory {
  static final List<Protocol> DEFAULT_PROTOCOLS = Util.immutableList(
      Protocol.HTTP_2, Protocol.HTTP_1_1);

  static final List<ConnectionSpec> DEFAULT_CONNECTION_SPECS = Util.immutableList(
      ConnectionSpec.MODERN_TLS, ConnectionSpec.CLEARTEXT);

  static {
    Internal.instance = new Internal() {
      @Override public void addLenient(Headers.Builder builder, String line) {
        builder.addLenient(line);
      }
      //提供静态方法对头部信息进行处理
      @Override public void addLenient(Headers.Builder builder, String name, String value) {
        builder.addLenient(name, value);
      }
      //写入缓存(响应数据缓存)
      @Override public void setCache(OkHttpClient.Builder builder, InternalCache internalCache) {
        builder.setInternalCache(internalCache);
      }
       //把连接变成空闲状态
      @Override public boolean connectionBecameIdle(
          ConnectionPool pool, RealConnection connection) {
        return pool.connectionBecameIdle(connection);
      }
       //从缓存中获取有效的连接, 从内存的ConnectiongPool中的Deque读取
      @Override public RealConnection get(ConnectionPool pool, Address address,
          StreamAllocation streamAllocation, Route route) {
        return pool.get(address, streamAllocation, route);
      }
      //对地址进行校验
      @Override public boolean equalsNonHost(Address a, Address b) {
        return a.equalsNonHost(b);
      }
      //多路复用?(待研究 StreamAllocation 类)
      @Override public Socket deduplicate(
          ConnectionPool pool, Address address, StreamAllocation streamAllocation) {
        return pool.deduplicate(address, streamAllocation);
      }
       //把连接添加到连接池当中,缓存起来
      @Override public void put(ConnectionPool pool, RealConnection connection) {
        pool.put(connection);
      }
       //获取连接池里面的连接,可以有效剔除黑名单的线路,用于优化连接效果。
      @Override public RouteDatabase routeDatabase(ConnectionPool connectionPool) {
        return connectionPool.routeDatabase;
      }
      //获取response 的 code
      @Override public int code(Response.Builder responseBuilder) {
        return responseBuilder.code;
      }
     //sslSocket 的连接协议,规范
      @Override
      public void apply(ConnectionSpec tlsConfiguration, SSLSocket sslSocket, boolean isFallback) {
        tlsConfiguration.apply(sslSocket, isFallback);
      }
      //检查 Url 正确性,可用性
      @Override public HttpUrl getHttpUrlChecked(String url)
          throws MalformedURLException, UnknownHostException {
        return HttpUrl.getChecked(url);
      }
      //获取到的 StreamAllocation(待研究) ,主要处理 Connections,Streams, Calls之间的关系
      @Override public StreamAllocation streamAllocation(Call call) {
        return ((RealCall) call).streamAllocation();
      }
      //新建web 相关的 Call
      @Override public Call newWebSocketCall(OkHttpClient client, Request originalRequest) {
        return new RealCall(client, originalRequest, true);
      }
    };
  }

  final Dispatcher dispatcher;
  final Proxy proxy;
  final List<Protocol> protocols;
  final List<ConnectionSpec> connectionSpecs;
  final List<Interceptor> interceptors;
  final List<Interceptor> networkInterceptors;
  final EventListener.Factory eventListenerFactory;
  final ProxySelector proxySelector;
  final CookieJar cookieJar;
  final Cache cache;
  final InternalCache internalCache;
  final SocketFactory socketFactory;
  final SSLSocketFactory sslSocketFactory;
  final CertificateChainCleaner certificateChainCleaner;
  final HostnameVerifier hostnameVerifier;
  final CertificatePinner certificatePinner;
  final Authenticator proxyAuthenticator;
  final Authenticator authenticator;
  final ConnectionPool connectionPool;
  final Dns dns;
  final boolean followSslRedirects;
  final boolean followRedirects;
  final boolean retryOnConnectionFailure;
  final int connectTimeout;
  final int readTimeout;
  final int writeTimeout;
  final int pingInterval;

  public OkHttpClient() {
    this(new Builder());
  }
  .
  .等等
  .
    // TODO(jwilson): make this public after the 3.7 release.
    /*public*/ Builder eventListener(EventListener eventListener) {
      if (eventListener == null) throw new NullPointerException("eventListener == null");
      this.eventListenerFactory = EventListener.factory(eventListener);
      return this;
    }

    // TODO(jwilson): make this public after the 3.7 release.
    /*public*/ Builder eventListenerFactory(EventListener.Factory eventListenerFactory) {
      if (eventListenerFactory == null) {
        throw new NullPointerException("eventListenerFactory == null");
      }
      this.eventListenerFactory = eventListenerFactory;
      return this;
    }

    public OkHttpClient build() {
      return new OkHttpClient(this);
    }
  }

这个类就复杂了首先说一下OkHttpClient这个类的整体设计,它采用门面也是外观模式来构造一个管理者的角色。client知晓子模块的所有配置以及提供需要的参数。client会将所有从客户端发来的请求委派到相应的子系统去。在类中,有多个子系统、类或者类的集合。例如上面的cache、连接以及连接池相关类的集合、网络配置相关类集合等等。每个子系统都可以被客户端直接调 用,或者被门面角色调用。子系统并不知道门面的存在,对于子系统而言,门面仅仅是另外一个客户端而已。同时,OkHttpClient可以看作是整个框架 的上下文。

其内部的种种子属性名字ProxyCookieJarCacheSSLSocketFactory是不是很熟悉?我们可以猜测其缓存,cookie,https等等功能都再次实现并控制,但是在此暂不详细一个个解释。让我们聚焦一下调用方式,也是它最重要的方法newCall返回一个Call对象(一个准备好了的可以执行和取消的请求)。而借此RequestOkHttpClient而这结合到一起了

Request与OkHttpClient的结合

结合方式如下:

Call call = okHttpClient.newCall(request);

在此,我们发现用一个Call对象就把两者结合在了一起,具体的就是调用了okHttpClientnewCall方法

@Override public Call newCall(Request request) {
return new RealCall(this, request, false /* for web socket */);
}

这个RealCall是个啥

  RealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {  //第三个参数false表示不是webSokcet)!    final EventListener.Factory eventListenerFactory = client.eventListenerFactory();
    this.client = client;
    this.originalRequest = originalRequest;
    this.forWebSocket = forWebSocket;
    this.retryAndFollowUpInterceptor = new RetryAndFollowUpInterceptor(client, forWebSocket);
    // TODO(jwilson): this is unsafe publication and not threadsafe.
    this.eventListener = eventListenerFactory.create(this);
  }

我们可以发现经过RealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {}这个构造方法,RealCall的属性被赋值并初始化了,接下来我们看一下RealCall这个类

final class RealCall implements Call {
  final OkHttpClient client;
  final RetryAndFollowUpInterceptor retryAndFollowUpInterceptor;
  final EventListener eventListener;

  /** The application's original request unadulterated by redirects or auth headers. */
  final Request originalRequest;
  final boolean forWebSocket;

  // Guarded by this.
  private boolean executed;

  RealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
    final EventListener.Factory eventListenerFactory = client.eventListenerFactory();

    this.client = client;
    this.originalRequest = originalRequest;
    this.forWebSocket = forWebSocket;
    this.retryAndFollowUpInterceptor = new RetryAndFollowUpInterceptor(client, forWebSocket);

    // TODO(jwilson): this is unsafe publication and not threadsafe.
    this.eventListener = eventListenerFactory.create(this);
  }

  @Override public Request request() {
    return originalRequest;
  }

  @Override public Response execute() throws IOException {
    synchronized (this) {
      if (executed) throw new IllegalStateException("Already Executed");
      executed = true;
    }
    captureCallStackTrace();
    try {
      client.dispatcher().executed(this);
      Response result = getResponseWithInterceptorChain();
      if (result == null) throw new IOException("Canceled");
      return result;
    } finally {
      client.dispatcher().finished(this);
    }
  }

  private void captureCallStackTrace() {
    Object callStackTrace = Platform.get().getStackTraceForCloseable("response.body().close()");
    retryAndFollowUpInterceptor.setCallStackTrace(callStackTrace);
  }

  @Override public void enqueue(Callback responseCallback) {
    synchronized (this) {
      if (executed) throw new IllegalStateException("Already Executed");
      executed = true;
    }
    captureCallStackTrace();
    client.dispatcher().enqueue(new AsyncCall(responseCallback));
  }

  @Override public void cancel() {
    retryAndFollowUpInterceptor.cancel();
  }

  @Override public synchronized boolean isExecuted() {
    return executed;
  }

  @Override public boolean isCanceled() {
    return retryAndFollowUpInterceptor.isCanceled();
  }

  @SuppressWarnings("CloneDoesntCallSuperClone") // We are a final type & this saves clearing state.
  @Override public RealCall clone() {
    return new RealCall(client, originalRequest, forWebSocket);
  }

  StreamAllocation streamAllocation() {
    return retryAndFollowUpInterceptor.streamAllocation();
  }

  final class AsyncCall extends NamedRunnable {
    private final Callback responseCallback;

    AsyncCall(Callback responseCallback) {
      super("OkHttp %s", redactedUrl());
      this.responseCallback = responseCallback;
    }

    String host() {
      return originalRequest.url().host();
    }

    Request request() {
      return originalRequest;
    }

    RealCall get() {
      return RealCall.this;
    }

    @Override protected void execute() {
      boolean signalledCallback = false;
      try {
        Response response = getResponseWithInterceptorChain();
        if (retryAndFollowUpInterceptor.isCanceled()) {
          signalledCallback = true;
          responseCallback.onFailure(RealCall.this, new IOException("Canceled"));
        } else {
          signalledCallback = true;
          responseCallback.onResponse(RealCall.this, response);
        }
      } catch (IOException e) {
        if (signalledCallback) {
          // Do not signal the callback twice!
          Platform.get().log(INFO, "Callback failure for " + toLoggableString(), e);
        } else {
          responseCallback.onFailure(RealCall.this, e);
        }
      } finally {
        client.dispatcher().finished(this);
      }
    }
  }

  /**
   * Returns a string that describes this call. Doesn't include a full URL as that might contain
   * sensitive information.
   */
  String toLoggableString() {
    return (isCanceled() ? "canceled " : "")
        + (forWebSocket ? "web socket" : "call")
        + " to " + redactedUrl();
  }

  String redactedUrl() {
    return originalRequest.url().redact();
  }

  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 (!forWebSocket) {
      interceptors.addAll(client.networkInterceptors());
    }
    interceptors.add(new CallServerInterceptor(forWebSocket));

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

OkHttpClient,EventListener,Request看起来这个类才是真正的网络请求的发起者管理者,查看一下源码。executeenqueue是一个很给力的方法他们分别用于同步和异步得执行网络请求。这其中他们两个都调用了同一个方法getResponseWithInterceptorChain,并且返回了同一个类的对象Response而我们可以发现在我们请求成功之后都会走下面的这个回调,

   @Override
   public void onResponse(Call call, Response response) throws IOException {      
   }

其中的重要返回参数就是Response;由此我们可以推测出来okhttp的种种拦截处理都在getResponseWithInterceptorChain中搞定了,但是我们想要知道他是怎么控制线程来完成请求的执行的
这个时候回看一下同步和异步请求

同步请求execute
  @Override public Response execute() throws IOException {
    synchronized (this) {
      if (executed) throw new IllegalStateException("Already Executed");
      executed = true;
    }
    //判断call是否执行过,可以看出每个Call对象只能使用一次原则。然后调用了captureCallStackTrace()方法。

    captureCallStackTrace(); //捕获了请求的StackTrace。
   //重点方法在此
    try {
      client.dispatcher().executed(this);看下方executed方法
      Response result = getResponseWithInterceptorChain();
      if (result == null) throw new IOException("Canceled");
      return result;
    } finally {
      client.dispatcher().finished(this);
    }
  }

这么我们暂且记下

  1. try方法执行了client.dispatcher().executed(this)
  2. try之后调用了 client.dispatcher().finished(this);

虽然1.才是我们真正的线程处理方法,但是现在我们先聚焦一下2看看finished做了什么

  void finished(RealCall call) {
    finished(runningSyncCalls, call, false);
  }

注意这里的参数runningSyncCalls和false这里我们对client.dispatcher().executed(this)埋个悬念

异步请求enqueue
  @Override public void enqueue(Callback responseCallback) {
    synchronized (this) {
      if (executed) throw new IllegalStateException("Already Executed");
      //executed默认为false,executed这个是一个标志,标志这个请求是否已经正在请求中

      executed = true;
    }
    captureCallStackTrace();
    client.dispatcher().enqueue(new AsyncCall(responseCallback));
       //重点查看OkHttpClient的Dispatcher的enqueue方法
  }

走到这一步的时候我们貌似卡死在了异步请求的执行上面,我们走不下去enqueue这个方法了,这个时候回头看OkHttpClient中client.dispatcher()做了啥,

    public Builder dispatcher(Dispatcher dispatcher) {
      if (dispatcher == null) throw new IllegalArgumentException("dispatcher == null");
      this.dispatcher = dispatcher;
      return this;
    }

发现就是返回一个Dispatcher对象,也就是其控制了okhttp的线程处理贴出其源码,这个类也就是线程控制类这下让我们带着同步和异步的两个疑问点看这个类

  1. 同步请求的client.dispatcher().executed(this)
  2. 异步请求的client.dispatcher().enqueue(new AsyncCall(responseCallback));

Dispatcher

public final class Dispatcher {
  private int maxRequests = 64;限制最大请求数目
  private int maxRequestsPerHost = 5;
  private Runnable idleCallback;

  /** Executes calls. Created lazily. */
  private ExecutorService executorService;

  /** Ready async calls in the order they'll be run. */

  储存准备中的异步请求队列
  private final Deque<AsyncCall> readyAsyncCalls = new ArrayDeque<>();


  /** Running asynchronous calls. Includes canceled calls that haven't finished yet. */
  储存运行中的异步请求队列
  private final Deque<AsyncCall> runningAsyncCalls = new ArrayDeque<>();



  /** Running synchronous calls. Includes canceled calls that haven't finished yet. */
  private final Deque<RealCall> runningSyncCalls = new ArrayDeque<>();

  public Dispatcher(ExecutorService executorService) {
    this.executorService = executorService;
  }

  public Dispatcher() {
  }

  public synchronized ExecutorService executorService() {
    if (executorService == null) {
      executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
          new SynchronousQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher", false));
    }
    return executorService;
  }
.
.省略部分
.
//异步请求的发起
synchronized void enqueue(AsyncCall call) {
    if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
      runningAsyncCalls.add(call);
      executorService().execute(call);
    } else {
      readyAsyncCalls.add(call);
    }
  }
.
.
.省略部分
.
  private void promoteCalls() {
    if (runningAsyncCalls.size() >= maxRequests) return; // Already running max capacity.
    if (readyAsyncCalls.isEmpty()) return; // No ready calls to promote.

    for (Iterator<AsyncCall> i = readyAsyncCalls.iterator(); i.hasNext(); ) {
      AsyncCall call = i.next();

      if (runningCallsForHost(call) < maxRequestsPerHost) {
        i.remove();

        runningAsyncCalls.add(call);
        executorService().execute(call);
      }

      if (runningAsyncCalls.size() >= maxRequests) return; // Reached max capacity.
    }
  }
.
.省略部分
.
  //同步方法调用此方法,将call加入到runningSyncCalls中。
  /** Used by {@code Call#execute} to signal it is in-flight. */
  synchronized void executed(RealCall call) {
    runningSyncCalls.add(call);
  }

  /** Used by {@code AsyncCall#run} to signal completion. */
  void finished(AsyncCall call) {
    finished(runningAsyncCalls, call, true);
  }

   同步运行调用的是此方法!
  /** Used by {@code Call#execute} to signal completion. */
  void finished(RealCall call) {
    finished(runningSyncCalls, call, false);
  }

  private <T> void finished(Deque<T> calls, T call, boolean promoteCalls) {
    int runningCallsCount;
    Runnable idleCallback;
    synchronized (this) {
      //看好这个判断条件!runningAsyncCalls实现了自减
      if (!calls.remove(call)) throw new AssertionError("Call wasn't in-flight!");
      if (promoteCalls) promoteCalls();

      //同步运行调用的是此方法!
      runningCallsCount = runningCallsCount();
      idleCallback = this.idleCallback;
    }

    if (runningCallsCount == 0 && idleCallback != null) {
      idleCallback.run();
    }
  }
.
.省略部分
.

  public synchronized int runningCallsCount() {
    return runningAsyncCalls.size() + runningSyncCalls.size();
  }

以下是对这个类的一些解读:

现在来再先看同步请求其经历过runningSyncCalls.add(call)将call插入到runningSyncCalls后再finaly中最终调用了finished方法 ,finshed (runningSyncCalls, call, false)最终我们经历了runningCallsCount = runningCallsCount();后,runningCallsCount就变成了判断现在是否有正在进行的网络请求的一个标识符,如果runningCallsCount == 0就说明线程空闲,直接run就可以了

现在再来看异步请求经历了一次线程池大小的判断后,如果当前正在等待运行的请求数目大于最大的请求数大小或者是相同Host最大请求数量之后则加入到readyAsyncCalls否则则加入到runningAsyncCalls在之后,
这个时候我们就去找这些个Call的执行位置了

我们一直所想找的就是线程的执行位置,为此,我们先回头看一下runningAsyncCallsreadyAsyncCalls,runningSyncCalls的声明。

  private final Deque<AsyncCall> readyAsyncCalls = new ArrayDeque<>();
  private final Deque<AsyncCall> runningAsyncCalls = new ArrayDeque<>();
  private final Deque<RealCall> runningSyncCalls = new ArrayDeque<>();

这下看起来要去AsyncCall和RealCall类进行查找执行代码了
得了,找父类AsyncCall

  final class AsyncCall extends NamedRunnable {}

继续找父类这里先看一下源码,我们发现了,他就是一个线程啊Runnable的具体实现execute方法,

public abstract class NamedRunnable implements Runnable {
  protected final String name;

  public NamedRunnable(String format, Object... args) {
    this.name = Util.format(format, args);
  }

  @Override public final void run() {
    String oldName = Thread.currentThread().getName();
    Thread.currentThread().setName(name);
    try {
      execute();
    } finally {
      Thread.currentThread().setName(oldName);
    }
  }

  protected abstract void execute();
}

抽象的execute方法我们回过头去看看AsyncCall

  final class AsyncCall extends NamedRunnable {
    private final Callback responseCallback;

    AsyncCall(Callback responseCallback) {
      super("OkHttp %s", redactedUrl());
      this.responseCallback = responseCallback;
    }

    String host() {
      return originalRequest.url().host();
    }

    Request request() {
      return originalRequest;
    }

    RealCall get() {
      return RealCall.this;
    }

    @Override protected void execute() {
      boolean signalledCallback = false;
      try {
        Response response = getResponseWithInterceptorChain();

        //最为重要的又是这getResponseWithInterceptorChain方法!

        if (retryAndFollowUpInterceptor.isCanceled()) {
          signalledCallback = true;
          responseCallback.onFailure(RealCall.this, new IOException("Canceled"));
        } else {
          signalledCallback = true;
          responseCallback.onResponse(RealCall.this, response);

           //这里对应call的onResponse(Call call, Response response) throws IOException {}


      } catch (IOException e) {
        if (signalledCallback) {
          // Do not signal the callback twice!
          Platform.get().log(INFO, "Callback failure for " + toLoggableString(), e);
        } else {
          responseCallback.onFailure(RealCall.this, e);

            //这里对应call的onFailure(Call call, IOException e) {}

                 } finally {

                 看好了这里的这个非常重要的方法!!!其调用方法在下面
        client.dispatcher().finished(this);
      }
    }

      /** Used by {@code AsyncCall#run} to signal completion. */
  void finished(AsyncCall call) {
    finished(runningAsyncCalls, call, true);
  }

  }
`

很好不负众望,异步的线程执行execute被找到了,这下我们再找找同步的执行在哪里同样的方式我去找RealCall类

  @Override public Response execute() throws IOException {
    synchronized (this) {
      if (executed) throw new IllegalStateException("Already Executed");
      executed = true;
    }
    captureCallStackTrace();
    try {
      client.dispatcher().executed(this);
      Response result = getResponseWithInterceptorChain();
      if (result == null) throw new IOException("Canceled");
      return result;
    } finally {
      client.dispatcher().finished(this);
    }
  }

等等AsyncCall居然是RealCall的内部类,有意思了让我们来对比一下他们主要做了什么事情

  1. try内均执行了相同的代码getResponseWithInterceptorChain
  2. 都走了finally内的 client.dispatcher().finished(this);

getResponseWithInterceptorChain方法再上文做了大体的推测,现在让我们看看finished做了什么

异步
  /** Used by {@code AsyncCall#run} to signal completion. */
  void finished(AsyncCall call) {
    finished(runningAsyncCalls, call, true);
  }


  同步
    /** Used by {@code Call#execute} to signal completion. */
  void finished(RealCall call) {
    finished(runningSyncCalls, call, false);
  }

有意思了runningSyncCalls和runningAsyncCalls,这连个字面意思的同步和异步都出来了,对了,注意一下第三个参数false和true

这个时候先看看finished源码

  private <T> void finished(Deque<T> calls, T call, boolean promoteCalls) {
    int runningCallsCount;
    Runnable idleCallback;
    synchronized (this) {

    //看好这个判断条件!runningAsyncCalls实现了自减,remove就自减
      if (!calls.remove(call)) throw new AssertionError("Call wasn't in-flight!");
      if (promoteCalls) promoteCalls();//记不记得同步和异步的true和false?这里上场了
      runningCallsCount = runningCallsCount();
      idleCallback = this.idleCallback;
    }

    if (runningCallsCount == 0 && idleCallback != null) {
      idleCallback.run();
    }
  }

promoteCalls做了什么!

  private void promoteCalls() {
    if (runningAsyncCalls.size() >= maxRequests) return; // Already running max capacity.
    if (readyAsyncCalls.isEmpty()) return; // No ready calls to promote.

    for (Iterator<AsyncCall> i = readyAsyncCalls.iterator(); i.hasNext(); ) {
      AsyncCall call = i.next();

      if (runningCallsForHost(call) < maxRequestsPerHost) {
        i.remove();
        runningAsyncCalls.add(call);
        executorService().execute(call);
      }

      if (runningAsyncCalls.size() >= maxRequests) return; // Reached max capacity.
    }
  }

循环遍历,将readyAsyncCalls中的元素一个个的加入到runningAsyncCalls中并再次调用execute()方法。直到所有的readyAsyncCalls集合变为空。这就借助Deque集合类,实现了等待队列和执行队列,牛逼,太方便了。

getResponseWithInterceptorChain()

上面的文章已经帮我们分析,我们已经可以很明确的发现了无论是异步请求还是同步请求均调用了getResponseWithInterceptorChain的方法,而这个方法是用来处理各种各样的拦截请求。

    Response getResponseWithInterceptorChain() throws IOException {
    // Build a full stack of interceptors.
    List<Interceptor> interceptors = new ArrayList<>();
    //添加开发者应用层自定义的Interceptor
    interceptors.addAll(client.interceptors());
    //这个Interceptor是处理请求失败的重试,重定向    
    interceptors.add(retryAndFollowUpInterceptor);
    //这个Interceptor工作是添加一些请求的头部或其他信息
    //并对返回的Response做一些友好的处理(有一些信息你可能并不需要)
    interceptors.add(new BridgeInterceptor(client.cookieJar()));
    //这个Interceptor的职责是判断缓存是否存在,读取缓存,更新缓存等等
    interceptors.add(new CacheInterceptor(client.internalCache()));
    //这个Interceptor的职责是建立客户端和服务器的连接
    interceptors.add(new ConnectInterceptor(client));
    if (!forWebSocket) {
      //添加开发者自定义的网络层拦截器
      interceptors.addAll(client.networkInterceptors());
    }
    interceptors.add(new CallServerInterceptor(forWebSocket));
    //一个包裹这request的chain
    Interceptor.Chain chain = new RealInterceptorChain(
        interceptors, null, null, null, 0, originalRequest);
    //把chain传递到第一个Interceptor手中
    return chain.proceed(originalRequest);
  }

我们发现他就是最终返回一个Response对象而其来源便是 经过各种拦截处理后发给服务器并被处理之后的返回结果。接下来我们就要分分析一下各种的Interceptor以及他们如何完成了参数拼装及网络结果回传。

本文先到此结束,下一篇着重介绍各种的Interceptor。