学习源码-OkHttp3之异步与多线程

发送一个异步请求

    OkHttpClient okhttpclient = new OkhttpClient.Builder()
              .readTimeout(READ_TIME_OUT_VALUE, TimeUnit.SECONDS)
              .writeTimeout(WRITE_TIME_OUT_VALUE, TimeUnit.SECONDS)
              .build();

    Request.Builder builder = new Request.Builder();
    Request request = builder.url(httpUrl).get().build();
    Call call = okhttpclient.newCall(request);
    call.enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        Log.d(TAG, "onFailure: ");
    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        Log.d(TAG, "onResponse: " + response.body().string());
    }
});

我们根据上一篇的经验,从RealCall入手,查看它的enqueue的具体实现:

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

我们关注一下最后一行代码,声明了一个新的AsyncCall并将responseCallback当做参数传入其中,那表示应该是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();
        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 {
          eventListener.callFailed(RealCall.this, e);
          responseCallback.onFailure(RealCall.this, e);
        }
      } finally {
        client.dispatcher().finished(this);
      }
    }
  }

以及NamedRunnable的源码:

/**
 * Runnable implementation which always sets its thread name.
 */
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();
}

AsyncCall继承了NamedRunnableNamedRunnableRunnable接口的实现,它的run方法为当前线程设置了name并执行了抽象方法execute()。回过头查看AsyncCall实现的execute()方法。最终还是通过getResponseWithInterceptorChain()方法得到的response,回到了上一章我们所研究的拦截器链。然后我们回归到RealCallenqueue方法,OkHttpClient中的dispatcher()管理AsyncCall。那可以察觉到,这个dispatcher()就是多线程控制器。

管理异步请求

我们找到Dispatcher的源码,查看它的enqueue方法:

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

代码中的executorService()真正执行了AsyncCall

  public synchronized ExecutorService executorService() {
    if (executorService == null) {
      executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
          new SynchronousQueue(), Util.threadFactory("OkHttp Dispatcher", false));
    }
    return executorService;
  }

通过代码我们发现,OkHttpClient最终通过构建线程池来管理异步任务。

你可能感兴趣的:(学习源码-OkHttp3之异步与多线程)