美文网首页
Okhttp 流程分析

Okhttp 流程分析

作者: 80de3cb7b548 | 来源:发表于2018-12-01 11:13 被阅读0次

最近打算将 最经常使用的 三个开源框架 Okhttp + Retrofit + Rxjava2 流程分析清楚, 写文章记录下来,也算是对自己思路的一个整理过程.

Okhttp Wiki 地址

一.okhttp的基本使用方法:
//1
OkHttpClient client = new OkHttpClient();

String run(String url) throws IOException {
//2
 Request request = new Request.Builder()
      .url(url)
      .build();
//3
  Response response = client.newCall(request).execute();
  return response.body().string();
}
  1. OkHttpClient 实现了 Call.Factory ,Call 负责执行请求和读取响应结果
  2. Request 是 Http 请求 (An HTTP request.)
  3. 通过 Call 对象 执行 Http请求, 并获取 Response , Response 是Http 请求的响应
    (An HTTP response)
二: 创建 OkhttpClient 对象:

OkHttpClient client = new OkHttpClient();

  public OkHttpClient() {
    this(new Builder());
  }

调用了自身的 OkHttpClient(Builder builder) 构造函数,如果我们外界没有配置的话,就全部使用默认参数

  OkHttpClient(Builder builder) {
    //默认参数赋值
  this.dispatcher = builder.dispatcher;
    this.proxy = builder.proxy;
    this.protocols = builder.protocols;
    this.connectionSpecs = builder.connectionSpecs;
    ...
  }

三: 创建 Http 请求

Request request = new Request.Builder().build();

    public Request build() {
      if (url == null) throw new IllegalStateException("url == null");
      return new Request(this);
    }

1.判断 请求的 url 是否 为 null, 为null 则直接抛出异常
2.返回一个 Request 对象

  Request(Builder builder) {
    this.url = builder.url;
    this.method = builder.method;
    this.headers = builder.headers.build();
    this.body = builder.body;
    this.tags = Util.immutableMap(builder.tags);
  }

在该构造函数内对 一个 Http 请求 的 url, method ,headers,body 进行赋值

    public Builder() {
      // 默认的请求方法
      this.method = "GET";
      this.headers = new Headers.Builder();
    }
四: 执行Http 请求

Response response = client.newCall(request).execute();
从使用方法看,我们知道请求是在 OkhttpClient 对象内调用了 newCall
我们先看下 OkhttpClient 里面的newCall 方法:

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

真正的Call 对象是通过 RealCall.newRealCall返回的.

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

我们看下 execute() 方法, RealCall 的 excut() 方法 是真正去执行请求的地方:

  @Override public Response execute() throws IOException {
    synchronized (this) {
      if (executed) throw new IllegalStateException("Already Executed");  //1
      executed = true;
    }
    captureCallStackTrace();
    eventListener.callStart(this);
    try {
      client.dispatcher().executed(this);       //2
      Response result = getResponseWithInterceptorChain();                   //3
      if (result == null) throw new IOException("Canceled");
      return result;
    } catch (IOException e) {
      eventListener.callFailed(this, e);
      throw e;
    } finally {
      client.dispatcher().finished(this);        //4  
    }
  }

这里面主要做了 几件事:

  1. 判断 Call 是否已经被执行
  2. client.dispatcher() 记录该Call 被执行
  /** Used by {@code Call#execute} to signal it is in-flight. */
  synchronized void executed(RealCall call) {
    runningSyncCalls.add(call);
  }
  1. 通过拦截器链获取响应结果
getResponseWithInterceptorChain 是真正执行 Http 请求,解析Resonse 的地方
  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());

    return chain.proceed(originalRequest);
  }
  1. client.dispatcher() 执行 finished 方法,将Call 从 runningSyncCalls 移除
 /** Used by {@code Call#execute} to signal completion. */
  void finished(RealCall call) {
    finished(runningSyncCalls, call, false);
  }

五. 具体看下 getResponseWithInterceptorChain 是如何执行请求,解析 响应信息的

...未完待续

相关文章

网友评论

      本文标题:Okhttp 流程分析

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