okhttp源码阅读

对okhttp的源码进行了阅读,主要是学习大神的写作思路。
官网上面的okhttp的例子,我们通过例子下手,来看源码。

OkHttpClient client = new OkHttpClient();
String run(String url) throws IOException {
  Request request = new Request.Builder()
      .url(url)
      .build();
  Response response = client.newCall(request).execute();
  return response.body().string();
}

一、 没别的,首页就是OkHttpClient这个类,这个类里面东西很多,作者用了建造者模式(Builder Pattern)。当然在例子里面看不出来,但是,作者在类的注释里面给了范例。

 // The singleton HTTP client.
public final OkHttpClient client = new OkHttpClient.Builder()
      .addInterceptor(new HttpLoggingInterceptor())
      .cache(new Cache(cacheDir, cacheSize))
      .build();

二、Request同样也是使用了建造者模式,这里面主要就请求的url,参数,请求头,请求体的设置。

 final HttpUrl url;
 final String method;
 final Headers headers;
 final RequestBody body;
 final Object tag;

三、 Response response = client.newCall(request).execute();
对于网络请求,出现在Call这个接口里面,而RealCall是具体的实现类,所以我们重点看RealCall这个类。
官方给的实例里面,调用了execute的方法,这个是同步请求,还有异步的请求enqueue方法。

  1. 同步的请求,直接返回了Response
@Override public Response execute() throws IOException {
    synchronized (this) {
      if (executed) throw new IllegalStateException("Already Executed");
      executed = true;
    }
    captureCallStackTrace();
    try {
      client.dispatcher().executed(this);
      Response result = getResponseWithInterceptorChain();
      if (result == null) throw new IOException("Canceled");
      return result;
    } finally {
      client.dispatcher().finished(this);
    }
  }

2.异步请求需要AsyncCall回调

@Override public void enqueue(Callback responseCallback) {
    synchronized (this) {
      if (executed) throw new IllegalStateException("Already Executed");
      executed = true;
    }
    captureCallStackTrace();
    client.dispatcher().enqueue(new AsyncCall(responseCallback));
  }

在AsyncCall里面调用execute方法

@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 {
          responseCallback.onFailure(RealCall.this, e);
        }
      } finally {
        client.dispatcher().finished(this);
      }
    }
  }
  1. 不管是同步还是异步,都会出现getResponseWithInterceptorChain()这个方法。这个okhttp的核心业务。
Response getResponseWithInterceptorChain() throws IOException {
    // Build a full stack of interceptors.
    List interceptors = new ArrayList<>();
    interceptors.addAll(client.interceptors());
    //重定向拦截器
    interceptors.add(retryAndFollowUpInterceptor);
    //对request进行重新封装以及对返回的response进行处理到用户可以使用
    interceptors.add(new BridgeInterceptor(client.cookieJar()));
    //缓存拦截器
    interceptors.add(new CacheInterceptor(client.internalCache()));
    //socket建立连接
    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);
    return chain.proceed(originalRequest);
  }

这个是一个拦截器列表, 每个拦截器有自己的作用,调用chain.proceed(originalRequest)方法,这里面使用了递归

 // Call the next interceptor in the chain.
    RealInterceptorChain next = new RealInterceptorChain(
        interceptors, streamAllocation, httpCodec, connection, index + 1, request);
    Interceptor interceptor = interceptors.get(index);
    Response response = interceptor.intercept(next);

在每个拦截器里面的intercept方法里面调用chain.proceed(originalRequest)。

你可能感兴趣的:(okhttp源码阅读)