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