2、okHttp3 源码分析

查看:okhttp源码解析_json_it的博客-CSDN博客_okhttp源码

查看:面试准备之okhttp的使用及源码分析(一)_ali18510953445的博客-CSDN博客

查看:Android面试题-OkHttp3源码分析_所有技术文章里面全部配置了配套视频-CSDN博客_android okhttp面试题

OkHttp3基本使用_李林杰的博客-CSDN博客_okhttp3

OkHttp3源码分析_李林杰的博客-CSDN博客_okhttp3源码解析

OkHttp 3.x 源码解析(一)之Interceptor 拦截器 - 云+社区 - 腾讯云

OkHttp 提交网络请求需要经过这样四个步骤:

  1. 初始化 OkHttpClient
  2. 创建 Request
  3. 创建 Call 对象(okHttpClient.newCall(request))
  4. 通过 call.excute 来发送同步请求,通过 call. enqueue 来发送异步请求

源码:

1、OkHttpClient

OkHttpClient 是通过 Builder 模式来创建实例对象的,Builder 模式常常用来复杂对象的构造,通过使用 Builder 模式可以减少构造器或方法调用传入的参数数量。

//内部构造器

public OkHttpClient() {

       this(new Builder());   //调用下面的Builder()方法

}

Builder是OkHttpClient的内部类, 这里主要定义了很多参数在构建OkHttpClient时通过builde添加,如果不添加则builde内部默认定义这些参数;

如下:

dispatcher:请求分发器

interceptors;  //拦截器

networkInterceptors; //网络拦截器
eventListenerFactory :Call的状态监听器
hostnameVerifier、 certificatePinner、 proxyAuthenticator、 authenticator:都是安全相关的设置
connectionPool:连接池,复用连接,我们通常将一个客户端和服务端和连接抽象为一个 connection,而每一个 connection 都会被存放在 connectionPool 中,由它进行统一的管理,例如有一个相同的 http 请求产生时,connection 就可以得到复用

2、Request

Request 同样也是使用了 Builder 模式来配置请求的url、设置get或者post请求的method 、body等等的参数.

3、Call

在创建了 OkHttpClient 和 Request 的实例对象之后,就可以通过调用 okHttpclient.newCall(request) 来创建一个 Call 对象。
OkHttpClient 的 newCall 方法实际上是调用了 RealCall(Call的实现类)的 newRealCall 方法.


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

4、同步请求 call.execute()

Call 对象就被 okHttpClient 的 newCall 方法给创建完成后,通过调用 call.execute() 来发送同步请求。

@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、根据executed标志判断当前的call是否被执行过,一个call只能执行一次,如果想要一个完全一样的 call,可以利用 all#clone 方法进行克隆。
2、利用 client.dispatcher().executed(this) 来进行实际执行,dispatcher 是刚才看到的 OkHttpClient.Builder 的成员之一,它的文档说自己是异步 HTTP 请求的执行策略,现在看来,同步请求它也有掺和。
3、最终的Response 是由getResponseWithInterceptorChain()函数获取 HTTP 返回结果,从函数名可以看出,这一步还会进行一系列“拦截”操作。
4、最后还要通知 dispatcher 自己已经执行完毕

execute 方法最关键的地方:

其一:

client.dispacher().executed(this);

 client.dispacher() 方法返回了一个 dispatcher 对象,然后接着调用了 dispacher 对象的 executed 方法来发送同步请求。

最后会调用 dispatcher 的 finished() 方法来将一个请求从请求队列中移除。

其二:

response返回值的获取:

Response result = getResponseWithInterceptorChain();

Response getResponseWithInterceptorChain() throws IOException {
    // Build a full stack of interceptors.
    List<Interceptor> interceptors = new ArrayList<>();
    interceptors.addAll(client.interceptors());      //     @1
    interceptors.add(retryAndFollowUpInterceptor);   //    @2
    interceptors.add(new BridgeInterceptor(client.cookieJar()));  //  @3
    interceptors.add(new CacheInterceptor(client.internalCache())); //   @4
    interceptors.add(new ConnectInterceptor(client));  //    @5
    if (!forWebSocket) {   //上面定义的是否为原始请求
      interceptors.addAll(client.networkInterceptors());   //   @6
    }
    interceptors.add(new CallServerInterceptor(forWebSocket));  //   @7  

    Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0,
        originalRequest, this, eventListener, client.connectTimeoutMillis(),
        client.readTimeoutMillis(), client.writeTimeoutMillis());

    return chain.proceed(originalRequest);         //     8
  }

由上面可知:
1、在配置 OkHttpClient 时设置的 interceptors;
2、负责失败重试以及重定向的 RetryAndFollowUpInterceptor;
3、负责把用户构造的请求转换为发送到服务器的请求、把服务器返回的响应转换为用户友好的响应的 BridgeInterceptor;
4、负责读取缓存直接返回、更新缓存的 CacheInterceptor;
5、负责和服务器建立连接的 ConnectInterceptor;
6、配置 OkHttpClient 时设置的 networkInterceptors;
7、负责向服务器发送请求数据、从服务器读取响应数据的 CallServerInterceptor。
8、开始链式调用

同步请求总结:拦截器用了责任链设计模式,它将请求一层一层向下传,知道有一层能够得到Resposne就停止向下传递,然后将response向上面的拦截器传递,然后各个拦截器会对respone进行一些处理,最后会传到RealCall类中通过execute来得到response。

5、异步请求

Okhttp 通过调用 Call 对象的 enqueue 来实现异步的网络请求。

enqueue 方法的前部分与 同步请求的 executed 方法相同,都是使用一个标志位 executed 来判断当前的 RealCall 对象是否已被执行过,如果已被执行过,则会抛出异常。
最后会调用 dispatcher 的 enqueue 方法来处理异步请求, enqueue 方法中传入了一个 封装了响应回调 callBack 的 AsyncCall 对象,AsyncCall 是 Runnable 的一个实现类。

//异步调用的方法
@Override public void enqueue(Callback responseCallback) {
    synchronized (this) {
      if (executed) throw new IllegalStateException("Already Executed");
      executed = true;
    }
    captureCallStackTrace();
    eventListener.callStart(this);
    client.dispatcher().enqueue(new AsyncCall(responseCallback));
  }

AysncCall中的execute()中的方法,同样是通过Response response = getResponseWithInterceptorChain();来获得response,这样异步任务也同样通过了interceptor,剩下的流程就和上面一样了。

6、Dispatcher

OkHttp 同步请求和异步请求都是有 dispatcher 这个分发器类来完成的。

client.dispatcher().executed(this);    //同步请求
client.dispatcher().enqueue(new AsyncCall(responseCallback));    //异步请求
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值