OkHttp 源码分析(一)

首先我们来看一段代码:

String url = "http://wwww.baidu.com";
OkHttpClient okHttpClient = new OkHttpClient();
final Request request = new Request.Builder()
        .url(url)
        .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());
    }
});

我们直接来看这一段

Call call = okHttpClient.newCall(request);

研究okhttpclient这个类之前,我们先来看看他都实现了那些类。

public class OkHttpClient implements Cloneable, Call.Factory, WebSocket.Factory {
}

我们这里只看 Call.Factory,webSocket.Factory一般app用不到。

public interface Call extends Cloneable {

            ...
            Response execute() throws IOException;//同步请求接口
            void enqueue(Callback responseCallback);//异步请求接口
            ...
            interface Factory {
                Call newCall(Request request);
            }
   }
这里我们就很明白newcall 的来历了。废话不多说直接看okhttpclient的newcall方法。
public class OkHttpClient implements Cloneable, Call.Factory, WebSocket.Factory {

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

}

然后进入realcall:

static RealCall newRealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
    // Safely publish the Call instance to the EventListener.
    RealCall call = new RealCall(client, originalRequest, forWebSocket);
    call.eventListener = client.eventListenerFactory().create(call);
    return call;
  }
 private RealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
    this.client = client;
    this.originalRequest = originalRequest;
    this.forWebSocket = forWebSocket;
    this.retryAndFollowUpInterceptor = new RetryAndFollowUpInterceptor(client, forWebSocket);
  }

这里我们看到比较重要的一个类RetryAndFollowUpInterceptor。重试/重定向 拦截器。这里我们不多做解析,后面的章节我们会详细的分析。

接下来就是

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());
    }
});

从上面的分析我们知道,这里的call 是RealCall,so...我们去看一下他的enqueue方法。(当然这里我们也看见了RealCall也是实现的Call接口)。

 @Override public void enqueue(Callback responseCallback) {
    synchronized (this) {
      if (executed) throw new IllegalStateException("Already Executed");
      executed = true;
    }
    ...
    client.dispatcher().enqueue(new AsyncCall(responseCallback));
  }
一个同步锁是否执行过的判断。然后我们来看一下这段代码:

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

这样,我们需求进入到okhttpclient中,

public class OkHttpClient implements Cloneable, Call.Factory, WebSocket.Factory {

    public Dispatcher dispatcher() {
        return dispatcher;
    }

    public static final class Builder {
        Dispatcher dispatcher;
        ...
    }
     public Builder() {
      dispatcher = new Dispatcher();
      ...
    }
}

接着,我们来看看Dispatcher。

public final class Dispatcher {
  private int maxRequests = 64;
  private int maxRequestsPerHost = 5;

  private @Nullable ExecutorService executorService;

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


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


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

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

...
  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.
    }
  }

  synchronized void executed(RealCall call) {
    runningSyncCalls.add(call);
  }


  private <T> void finished(Deque<T> calls, T call, boolean promoteCalls) {
    int runningCallsCount;
    Runnable idleCallback;
    synchronized (this) {
      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();
    }
  }

}

好吧有点多,我们来看看都是啥,首先Dispatcher是一个调度器maxRequests最大请求为64,maxRequestsPerHost每个主机最多请求数为5。

  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;
  }

生成了一个可以无限大的 存活周期60s的线程池。

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


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


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

三个队列,一个同步请求的队列runningSyncCalls,两个异步请求使用的队列(readyAsyncCalls为等待请求的队列,runningAsyncCalls为正在请求的队列)。

好了继续enqueue方法,很明显,我们要先看一下AsyncCall。
final class AsyncCall extends NamedRunnable {
    
...
    Request request() {
      return originalRequest;
    }
...

    @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);
      }
    }
  }

这是一个可以命名的线程。最重要的方法execute。因为设计到okhttpclient的拦截机制,我们后面会详细分析。

现在我们终于来到了

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

我们进入到dispatcher可知:

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

如果runningAsyncCalls大小小于64,这个接口主机请求小于5 ,这时就会把call 添加到正在请求的队列中,并且通过executorService的调度执行AsyncCall的execute方法,最终通过    Response response = getResponseWithInterceptorChain(); 获取到Response通过Callback返回。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值