okhttp execute流程解析

okhttp execute流程解析

Android小彩虹2021-07-10 10:00:36120A+A-

okhttp运行

  new Thread(new Runnable() {
            @Override
            public void run() {
                okHttpClient.newCall(new Request.Builder().build()).enqueue(new Callback() {
                    @Override
                    public void onFailure(Call call, IOException e) {

                    }

                    @Override
                    public void onResponse(Call call, Response response) throws IOException {

                    }
                });

            }
        }).start();

okhttp的同步运行方式如上,需要在子线程调用,我们先分析

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

此处创建了一个realCall,此处执行的是realcall的execute

@Override public Response execute() throws IOException {
    同一个网络请求不可同时执行两次以上,否则会异常
    synchronized (this) {
      if (executed) throw new IllegalStateException("Already Executed");
      executed = true;
    }
    transmitter.timeoutEnter();
    transmitter.callStart();
    try {
 1:     client.dispatcher().executed(this);
 2:     return getResponseWithInterceptorChain();
    } finally {
结束之后将请求移除出队列
      client.dispatcher().finished(this);
    }
  }

接下来看1出的dispatcher的方法

 /** Used by {@code Call#execute} to signal it is in-flight. */
  synchronized void executed(RealCall call) {
    runningSyncCalls.add(call);
  }

public final class Dispatcher {
  private int maxRequests = 64;
  private int maxRequestsPerHost = 5;
  private @Nullable Runnable idleCallback;

  /** Executes calls. Created lazily. */
  private @Nullable ExecutorService executorService;

  /** Ready async calls in the order they'll be run. */
异步请求队列
  private final Deque<AsyncCall> readyAsyncCalls = new ArrayDeque<>();
正在运行的异步请求队列
  /** Running asynchronous calls. Includes canceled calls that haven't finished yet. */
  private final Deque<AsyncCall> runningAsyncCalls = new ArrayDeque<>();
同步请求队列
  /** Running synchronous calls. Includes canceled calls that haven't finished yet. */
  private final Deque<RealCall> runningSyncCalls = new ArrayDeque<>();

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

  public Dispatcher() {
  }
}

此处dispatcher就是存储和移除每个请求的地方,每次执行execute或者enqueue的时候dispatcher的功能都只是将请求添加到队列中,重点是上处的2  getResponseWithInterceptorChain  这个方法才是真正运行请求的地方

 Response getResponseWithInterceptorChain() throws IOException {
    // Build a full stack of interceptors.
    List<Interceptor> interceptors = new ArrayList<>();
    interceptors.addAll(client.interceptors());,自定义的intercepters
    interceptors.add(new RetryAndFollowUpInterceptor(client));
    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, transmitter, null, 0,
        originalRequest, this, client.connectTimeoutMillis(),
        client.readTimeoutMillis(), client.writeTimeoutMillis());

    boolean calledNoMoreExchanges = false;
    try {
      Response response = chain.proceed(originalRequest);
      if (transmitter.isCanceled()) {
        closeQuietly(response);
        throw new IOException("Canceled");
      }
      return response;
    } catch (IOException e) {
      calledNoMoreExchanges = true;
      throw transmitter.noMoreExchanges(e);
    } finally {
      if (!calledNoMoreExchanges) {
        transmitter.noMoreExchanges(null);
      }
    }
  }

上处第一步加入了用户自定义的拦截器,之后加入了系统自定义的五个拦截器

RetryAndFollowUpInterceptor 重试拦截器

BridgeInterceptor 此处会把网络数据封装成http的格式,请求到服务器,并解析返回的http格式的数据

CacheInterceptor 缓存拦截器,处理用户自定义的缓存策略

ConnectInterceptor 连接服务器的拦截器,连接服务器用到socket协议,

networkInterceptors 网络日志拦截器

CallServerInterceptor 此处是socket真正建立连接的地方。

然后创建了一个 RealInterceptorChain,index是0, 此处是把okhttp的请求封装成一个个的数组链,一步步执行数组里面的链节点,这种封装很好的解耦了,各个模块的功能,还方便用户自定义链节点,处理网络访问中间的流程。

之后调用的RealInterceptorChain的proceed方法,我们看下

 public Response proceed(Request request, Transmitter transmitter, @Nullable Exchange exchange) throws IOException {...
// Call the next interceptor in the chain.
    RealInterceptorChain next = new RealInterceptorChain(interceptors, transmitter, exchange,
        index + 1, request, call, connectTimeout, readTimeout, writeTimeout);
    Interceptor interceptor = interceptors.get(index);
    Response response = interceptor.intercept(next);
try {
      Response response = chain.proceed(originalRequest);
      if (transmitter.isCanceled()) {
        closeQuietly(response);
        throw new IOException("Canceled");
      }
...
}

此处是从0遍历拦截器数组 并递归调用每个chain的intercepter方法进行拦截,然后调用proceed方法获取每个chain的response并让这个返回值传递下去。

所以从以上分析,我们可知每个请求都会经历这一系列的 chain,并获取到response。

点击这里复制本文地址 以上内容由权冠洲的博客整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!

支持Ctrl+Enter提交

联系我们| 本站介绍| 留言建议 | 交换友链 | 域名展示
本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除

权冠洲的博客 © All Rights Reserved.  Copyright quanguanzhou.top All Rights Reserved
苏公网安备 32030302000848号   苏ICP备20033101号-1

联系我们