Android Okhttp3 distributor source code analysis

In OkHttp, Dispatcher is the component responsible for scheduling and executing network requests. It manages the number of concurrent requests and the priority of requests to ensure the rational use of the underlying connection pool and thread pool, thereby improving the efficiency and performance of network requests .

By default, OkHttp uses a singleton dispatcher which can handle a maximum of 64 simultaneous requests. It is also possible to modify these default settings to meet specific needs by customizing the distributor.


Take an asynchronous request as an example:

package okhttp3;

final class RealCall implements Call {
  // ...

  @Override public void enqueue(Callback responseCallback) {
    // ...

    client.dispatcher().enqueue(new AsyncCall(responseCallback));
  }
  // ...
}

After executing Call.enqueue(), call to Dispatcher.enqueue():


package okhttp3;

public final class Dispatcher {
  private int maxRequests = 64;       // 最大请求数量
  private int maxRequestsPerHost = 5; // 同 Host 下最大请求数量

  private final Deque<AsyncCall> readyAsyncCalls = new ArrayDeque<>();   // 异步准备队列
  private final Deque<AsyncCall> runningAsyncCalls = new ArrayDeque<>(); // 异步执行队列
  private final Deque<RealCall> runningSyncCalls = new ArrayDeque<>();   // 同步执行队列

  synchronized void enqueue(AsyncCall call) {
    if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
      runningAsyncCalls.add(call);
      executorService().execute(call); // 线程池执行
    } else {
      readyAsyncCalls.add(call);
    }
  }
  // ...
}

It can be seen that Dispatcher defines three columns to store tasks in each state, so as to facilitate the management of tasks in each state . After calling Dispatcher.enqueue(), it will control whether the task is executed according to the current number of requests. If the number of current requests is too large, it will be stored in the asynchronous waiting queue first.


When can the tasks stored in the waiting queue be favored? Let's first look at the method Dispatcher.promoteCalls() of the operation preparation queue:

package okhttp3;

public final class Dispatcher {
  // ...

  private void promoteCalls() {
    if (runningAsyncCalls.size() >= maxRequests) return; // 是否达到最大请求次数
    if (readyAsyncCalls.isEmpty()) return; // 判断准备队列是否为空

    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; // 是否达到最大请求次数
    }
  }
  // ...
}

This method is to query whether there are unexecuted tasks in the preparation queue , and if so, execute them in the thread pool


When will this method be executed in an asynchronous request?

package okhttp3;

final class RealCall implements Call {

  final class AsyncCall extends NamedRunnable {
    // ...

    @Override protected void execute() {
      try {
        // ...异步请求
      } catch (IOException e) {
        // ...异常处理
      } finally {
        client.dispatcher().finished(this); // 调用
      }
    // ...
  }
}


// Dispatcher

  void finished(AsyncCall call) {
    finished(runningAsyncCalls, call, true);
  }

  private <T> void finished(Deque<T> calls, T call, boolean promoteCalls) {

      if (promoteCalls) promoteCalls(); // 调用了 promoteCalls()
  }

After calling finished() after the asynchronous request , it will eventually poll the preparation queue to see if there are any unexecuted tasks . This is the complete flow of asynchronous requests.

Synchronization is relatively simple, directly add tasks to the synchronization request queue, and it will not start


Summary: OkHttp's distributor plays a very important role in the network request process. It effectively manages concurrent requests, optimizes the order and execution of requests, and manages connection pools and thread pools to provide efficient and reliable network request functions.

Guess you like

Origin blog.csdn.net/weixin_47592544/article/details/131540648