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

Posted JMW1407

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android:OkHttp同步和异步请求流程的理解和使用相关的知识,希望对你有一定的参考价值。

OkHttp 请求分发机制

在这里插入图片描述

1、请求操作 Call

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

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

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

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

2、发起同步请求 execute()

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

在这里插入图片描述
处理流程如下:

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 处理。
在这里插入图片描述
处理流程如下:

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

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

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

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

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

参考

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

以上是关于Android:OkHttp同步和异步请求流程的理解和使用的主要内容,如果未能解决你的问题,请参考以下文章

Android开源框架&Okhttp网络框架解析

Android 中Okhttp的同步请求与异步请求

Android网络请求框架—OKHttp 源码解析

Android 进阶之探索 OkHttp 原理

Android网络请求框架—OKHttp 源码解析

Android网络请求框架—OKHttp 源码解析