Android Retrofit源码流程分析二(Retrofit

2022-11-26  本文已影响0人  Bfmall

接着第一篇:

继续跟踪 HttpServiceMethod.parseAnnotations 如下图:


image.png

同时在 HttpServiceMethod 类中发现了 invoke 的实现:


image.png

以我们最初的 Demo 代码段为例,并没有写在 Kotlin 协程方法中,所以会进入
if (!isKotlinSuspendFunction) 判断,返回一个 CallAdapted 对象。
由以上这些信息可以推断出:

1.Retrofit.loadServiceMethod() 实际返回的是一个 CallAdapter 对象。
2.Retrofit.create() 方法最后调用的 loadServiceMethod(method).invoke(args) 调用到了 HttpServiceMethod.invoke(),而 HttpServiceMethod.invoke() 又调用了自身的 adapt()。

那么就相当于 loadServiceMethod(method).invoke(args) 调用到了 CallAdapted 的 adapt()。这一通调用流程搞通后,我们来看看 CallAdapted 的 adapt(),如下图:


image.png

CallAdapted 类中包含一个 callAdapter,而这个 callAdapter 的赋值在构造器中,CallAdapted是在 HttpServiceMethod.parseAnnotations 方法中被new出来的,我们回看HttpServiceMethod.parseAnnotations的代码:


image.png

callAdapter 是由 createCallAdapter 方法返回,我们点进去看代码:


image.png

createCallAdapter 方法又调用了 retrofit.callAdapter()方法,我们回到 Retrofit 类中查看 callAdapter 方法:


image.png

callAdapter 是通过 Retrofit 类中的 callAdapterFactories 中取出的,接着看一下 callAdapterFactories 是什么:


image.png

是一个 List 容器,找一下他的初始化代码:


image.png

在 Retrofit.build() 方法中默认调用了 platform.defaultCallAdapterFactories() 添加了一个 CallAdapter.Factory,接着看一下 defaultCallAdapterFactories 的实现:


image.png

由源码可以看出,最后的三目表达式无论如何都构造了一个list返回 ,并且这个list 中添加了一个 DefaultCallAdapterFactory,看一下其内部实现:


image.png

他的 get 方法返回了一个匿名 CallAdapter 对象,其 adapt 方法则返回了一个 ExecutorCallbackCall 对象,点进去看他的实现:


image.png

注意上面代码中的 callbackExecutor,是切换到主线程执行,这块代码先留个疑问,在文章最后会再次分析他是如何初始化的。到这里为止,可以总结出实例代码中的 enqueue 实际调用的就是ExecutorCallbackCall 的 enqueue,其中的 delegate 变量需要注意下,是在 HttpServiceMethod 的adapt方法中传入的:


image.png

这个 call 是 OkHttpCall ,这里也先按下不表,跟了这么一长串的源码,先来稍微总结下整体的调用流程。

调用流程总结
1.首先由动态代理入手,从Retrofit.create()源码开始分析,其返回了 loadServiceMethod(method).invoke(),由于 invoke 是一个接口,我们需要找出 loadServiceMethod 返回的具体是什么。
2.loadServiceMethod 内部调用了 ServiceMethod.parseAnnotations ,parseAnnotations 调用了 HttpServiceMethod.parseAnnotations,通过其代码分析出返回了一个 CallAdapted 对象。由此分析出第一步中调用的 invoke 方法即为 CallAdapted 的 invoke。
3.CallAdapted 的 invoke 方法调用了其内部变量 callAdapter 的 adapte 方法,接着继续从源码查找 callAdapter 是如何初始化的。
4.在 Retrofit 类中发现 callAdapter 是通过内部变量 callAdapterFactories 容器中取出并且调用其 get 方法获得。
5.接着在 Retrofit 的 build 方法中发现 callAdapterFactories 默认会添加一个 DefaultCallAdapterFactory 类型的元素,其 get 方法实现返回了一个匿名的 CallAdapter 对象,其 adapt 方法返回了一个 ExecutorCallbackCall 对象。由此得出示例代码中执行请求的enqueue方法最终会调用到 ExecutorCallbackCall 对象的 enqueue 方法。
6.在 ExecutorCallbackCall 的 enqueue 方法中实现了发起请求触发回调以及线程的切换。
看完这一系列的调用流程后,必然有两个疑问:

上面的源码分析并没有看到对 OkHttp 的封装,Retrofit 是如何封装 OkHttp 发起请求的?
1.Retrofit 的线程切换存疑,在 ExecutorCallbackCall 的 enqueue 方法中触发回调时 2.callbackExecutor 为什么是切回到主线程?
下面来针对这两个问题再做一系列的源码分析!

————————————————
版权声明:本文为CSDN博主「孙先森i」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_38356174/article/details/124558387

上一篇下一篇

猜你喜欢

热点阅读