OkHttp同步和异步请求流程的理解和使用

  • OkHttp 请求分发机制
  • 1、请求操作 Call
  • 2、发起同步请求 execute()
  • 3、发起异步请求 enqueue()
  • 参考


OkHttp 请求分发机制

android binder 同步阻塞 android同步和异步请求_OkHttp同步

1、请求操作 Call

android binder 同步阻塞 android同步和异步请求_同步请求_02


在我们创建请求 Request 后,我们要用 OkHttpClient.newCall() 创建一个 RealCall 对象,然后调用 execute() 发起同步请求或调用 enqueue() 发起异步请求

RealCall 实现了 Call 接口,也是这个接口唯一的实现类,按注释来说,RealCall 是一个 OkHttp 应用与网络层之间的桥梁,该类暴露了高级应用层的原语(primitives):连接、请求、响应与流

你也可以把 RealCall 理解为同步请求操作,而 RealCall 的内部类 AsyncCall 则是异步请求操作

RealCall 中比较中要的两个方法的实现:execute()enqueue()

2、发起同步请求 execute()

当我们调用 RealCall.execute() 发起同步请求时,如果该请求已执行,那么会抛出非法状态异常,所以我们在发起同步请求时要注意捕获异常

android binder 同步阻塞 android同步和异步请求_android binder 同步阻塞_03


处理流程如下:

1、如果请求没有被执行的话,execute() 方法则会调用 AsyncTimeoutenter() 方法让 AsyncTimeout 做请求超时判断AsyncTimeout 中有一个继承了 Thread 的内部类 WatchDog,而 AsyncTimeout 会用 Object.wait/notify() 阻塞和唤醒 Watchdog 线程

2、当请求超时时,AsyncTimeout 会调用 RealCall 中实现的 timeOut() 方法关闭连接。

3、RealCallexecute() 方法调用完 enter() 方法后,会调用 Dispatcherexecuted() 把请求加入同步请求队列,然后调用 getResponseWithInterceptorChain() 方法获取响应,获取到响应后就会让 Dispatcher 把请求从同步请求队列中移除。

3、发起异步请求 enqueue()

当该请求还没有被执行时,execute() 方法会创建一个异步请求操作 AsyncCall,并把它交给 Dispatcher 处理。

android binder 同步阻塞 android同步和异步请求_OkHttp同步_04


处理流程如下:

1、AsyncCall 实现了 Runnable 接口,Dispatcher 接收到 AsyncCall 后,会把 AsyncCall 添加到待执行异步请求队列 readyAsyncCalls 中,然后调用自己的 promoteAndExecute() 方法。

2、把 AsyncCall 加入到异步请求队列后,Dispatcher 会看情况决定什么时候执行该异步请求,要执行的时候就会把请求任务提交到线程池 ExecutorService 中。

3、和同步请求一样,在 AsyncCallrun() 方法中做的第一件事情就是让 AsyncTimeout 进入超时判断逻辑,然后用拦截器链获取响应。

android binder 同步阻塞 android同步和异步请求_同步请求_05


4、当请求的过程中没有遇到异常时,AsyncCallrun() 方法就会调用我们设定的 CallbackonResposne() 回调,如果遇到了异常,则会调用 onFailure() 方法

5、不论异步请求是成功还是失败,RealCall 最后都会调用 Dispatcherfinished() 方法把请求从已运行异步请求队列 runningAsyncCalls 中移除。

参考

1、https://www.jianshu.com/p/5a12ae6d741a