OkHttp3源码学习之Call

介绍

Call接口对应于应用层,RealCall继承了Call接口,实现一次事务(Request-Response)的逻辑,下面来分析一下RealCall

源码分析

OkHttp3源码学习之Call_第1张图片
RealCall源码结构

RealCall需要重点分析 executeenqueuegetResponseWithInterceptorChain()

execute

execute用于发起同步请求

@Override public Response execute() throws IOException {
    //判断是否发起过请求
    synchronized (this) {
      if (executed) throw new IllegalStateException("Already Executed");
      executed = true;
    }
    //捕获异常信息
    captureCallStackTrace();
    try {
      //通过dispatcher()分发器添加,发起同步请求
      client.dispatcher().executed(this);
      //责任链模式获得请求结果
      Response result = getResponseWithInterceptorChain();
      //判断请求是否取消
      if (result == null) throw new IOException("Canceled");
      return result;
    } finally {
      //不管请求是否成功,dispatcher().finished()释放线程
      client.dispatcher().finished(this);
    }
  }

enqueue和AsyncCall

enqueue发起异步请求,大体和execute差不多,不同在于异步线程请求
client.dispatcher().enqueue(new AsyncCall(responseCallback));

AsyncCall

  final class AsyncCall extends NamedRunnable {
    private final Callback responseCallback;

    AsyncCall(Callback responseCallback) {
      super("OkHttp %s", redactedUrl());
      this.responseCallback = responseCallback;
    }
   ...
    @Override protected void execute() {
      //辅助判断是否抛出过异常
      boolean signalledCallback = false;
      try {
        //责任链获取response
        Response response = getResponseWithInterceptorChain();
        if (retryAndFollowUpInterceptor.isCanceled()) {
          signalledCallback = true;
          //返回异常,需要注意的是这个调用依然处于异步线程,而不是UI线程
          //不能在这里处理UI更新等主线程事件
          responseCallback.onFailure(RealCall.this, new IOException("Canceled"));
        } else {
          signalledCallback = true;
          //服务器正确响应,返回response,同为异步线程
          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);
      }
    }
  }

getResponseWithInterceptorChain()

构建拦截器,通过chain.proceed()分发Request,组建Response

  Response getResponseWithInterceptorChain() throws IOException {
    // Build a full stack of interceptors.
    List interceptors = new ArrayList<>();
    //用户自定义拦截器,例如回调主线程,Gson解析等等
    interceptors.addAll(client.interceptors());
   //失败重连和重定向拦截器
    interceptors.add(retryAndFollowUpInterceptor);
   //主要是对header的处理,包括设置cookie,gzip压缩等
    interceptors.add(new BridgeInterceptor(client.cookieJar()));
   //缓存拦截器
    interceptors.add(new CacheInterceptor(client.internalCache()));
   //连接层拦截器,用于连接管理,包括连接复用
    interceptors.add(new ConnectInterceptor(client));
    if (!forWebSocket) {
      //用户自定义的网络层拦截器,这里可以拿到初始的response
      interceptors.addAll(client.networkInterceptors());
    }
    //IO拦截器
    interceptors.add(new CallServerInterceptor(forWebSocket));
    //初始化一个拦截器链
    Interceptor.Chain chain = new RealInterceptorChain(
        interceptors, null, null, null, 0, originalRequest);
    //chain.proceed()从这里开始一次真正的Request-Response
    return chain.proceed(originalRequest);
  }

简单使用

OkHttpClient client = builder.build();
Request request = new Request.Builder().url("https://yq.aliyun.com/articles/78105?spm=5176.100239.blogcont78101.12.AHn7Zl")
                .build();
client.newCall(request).enqueue(new okhttp3.Callback() {
       @Override
        public void onFailure(okhttp3.Call call, IOException e) {}

        @Override
        public void onResponse(okhttp3.Call call, okhttp3.Response response) throws IOException { }
});

扩展

责任链模式可以简单理解为通过递归解除请求者(Request)与服务者(Response)之间的耦合,具体可查看《Java设计模式》职责链

你可能感兴趣的:(OkHttp3源码学习之Call)