okHttp

作者: 吃羊的草 | 来源:发表于2021-06-30 13:22 被阅读0次

https://blog.csdn.net/pxq10422/article/details/104784676 缓存拦截器
https://blog.csdn.net/freak_csh/article/details/95009057 连接拦截器
https://www.jianshu.com/p/be204b73c1ee CallServerInterceptor 拦截器

WechatIMG42.png WechatIMG43.png

Dispatcher 分发类

维护了三个队列,一个线程池

Dispatcher成员变量介绍
int maxRequests = 64;
默认同时执行的最大请求数, 可以通过setMaxRequests(int)修改.

int maxRequestsPerHost = 5;
每个主机默认请求的最大数目, 可以通过setMaxRequestsPerHost(int)修改.

private @Nullable Runnable idleCallback;
调度没有请求任务时的回调.

ExecutorService executorService;
执行异步请求的线程池,默认是 核心线程为0,最大线程数为Integer.MAX_VALUE,空闲等待为60s.

Deque<AsyncCall> readyAsyncCalls = new ArrayDeque<>();
异步请求的执行顺序的队列.

Deque<AsyncCall> runningAsyncCalls = new ArrayDeque<>();
运行中的异步请求队列.

Deque<RealCall> runningSyncCalls = new ArrayDeque<>();
运行中的同步请求队列.

同步请求时,通过调用dispatcher的executed方法,将请求添加到runningSyncCalls队列中

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

异步请求时,调用dispatcher的enqueue方法,将请求添加到readyAsyncCalls队列,再调用promoteAndExecute,取出readyAsyncCalls中的最后一个,判断当前runningSyncCalls运行队列中的数量不超过64个,并且同一域名的请求不大于5个,则将readyAsyncCalls取出的任务加入线程池中去执行网络请求。

private boolean promoteAndExecute() {
    assert (!Thread.holdsLock(this));

    List<AsyncCall> executableCalls = new ArrayList<>();
    boolean isRunning;
    synchronized (this) {
      for (Iterator<AsyncCall> i = readyAsyncCalls.iterator(); i.hasNext(); ) {
        AsyncCall asyncCall = i.next();

        if (runningAsyncCalls.size() >= maxRequests) break; // Max capacity.
        if (asyncCall.callsPerHost().get() >= maxRequestsPerHost) continue; // Host max capacity.

        i.remove();
        asyncCall.callsPerHost().incrementAndGet();
        executableCalls.add(asyncCall);
        runningAsyncCalls.add(asyncCall);
      }
      isRunning = runningCallsCount() > 0;
    }

    for (int i = 0, size = executableCalls.size(); i < size; i++) {
      AsyncCall asyncCall = executableCalls.get(i);
      asyncCall.executeOn(executorService());
    }

    return isRunning;
  }

okhttp的拦截器

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, this, eventListener, client.connectTimeoutMillis(),
        client.readTimeoutMillis(), client.writeTimeoutMillis());

    Response response = chain.proceed(originalRequest);
    if (retryAndFollowUpInterceptor.isCanceled()) {
      closeQuietly(response);
      throw new IOException("Canceled");
    }
    return response;
  }

相关文章

网友评论

      本文标题:okHttp

      本文链接:https://www.haomeiwen.com/subject/dhqjeltx.html