Retrofit 源码解析

1,147 阅读3分钟

梳理retrofit源码时做的一些记录,但也是挺久之前写的东西呢,感觉分析的不够流畅,跳跃性比较大

当时是带着这几个问题去看源码的

1.整个请求的流程是怎样的?
2.底层是如何用 OkHttp 请求的?
3.Okhttp是异步的,retrofit是怎么帮我们切换到主线程的?
4.注解是什么时候解析的,怎么解析的?
5.Converter和CallAdapter的作用?
6.如何支持 Kotlin协程的suspend挂起函数的?

Retrofit的简单流程图

1.png

根据流程图进入,首先是Retrofit.build()

2.png

重点1

  • 因为我们一般都不会传入callbackExecutor(回调执行器),所以他会进入到platform.defaultCallbackExecutor()语句但是我们直接点进去看的话,会发现,啥也没有 image.png

  • 那就先从platform入手吧,进入之后能看到 (其实英语也知道platform就是平台的意思,这里就是做一个平台的区分) image.png

  • 接着再进入Android()平台,所以这里可以认为callbackExecutor == MainThreadExecutor 用来切换线程

3.png

重点2

  • 可以看到上一步拿到的callbackExecutor 作为参数传入了platform.defaultCallAdapterFactories(callbackExecutor),继续跟进可以看到 4.png

  • 接着进入DefaultCallAdapterFactory 5.png

  • 在进入ExecutorCallbackCall 6.png

  • 这就是发起网络请求后,Retrofit帮我们切换到主线程的流程,总得来说就是在build方法中,通过Platform的子类Android()添加了一个默认的Executor:MainThreadExecutor,然后还添加了一个DefaultCallAdapterFactory并创建了匿名内部类CallAdapterMainThreadExecutor,包装成ExecutorCallbackCall,在网络请求回调,通过它切换线程,并把结果抛出去

重点3

  • 如果你没添加ConverterFacTory的话,默认会通过这个转换数据,你也可以通过继承Converter.FacTory自定义自己的数据转换。Gson的就是这样做的。 7.png

接着Retrofit.create()

这个方法看起来很简单就是通过动态代理获取interface的实例,接着你就可以调用方法了 当我们通过实例调用方法时,就会进入InvocationHandler.invoke,重点在这里面

8.png

先进入到看一看ServiceMethod

  • 进入loadServiceMethod,方法很简单,就是先从自己保存的中查找,没有则生成再保存下来,以后可以复用。

9.png

  • 方法返回值ServiceMethod在进入看看是个什么 10.png

  • 这里继续引出RequestFactory,里面都是方法注解的处理。需要注意的是对kotlin协程的适配在RequestFactory的build方法中,会遍历所有参数,去解析他们 image.png

  • 在跟进到parseParameter,我们知道kotlin在编译时候,会给方法最后后面添加一个Continuation<T>的参数 11.png

  • 而这个标志位会保存在requestFactory然后传入HttpServiceMethod!!这里写错了,这里responseType应该是Continuation里面的泛型<T>!! 12.png

13.png

普通方法进入的CallAdapted (写错了,应该是loadServiceMethod(method).invoke()调用的) 12417772-b46616fb1827c138.png

12417772-3073f311684ad39e.png

suspend方法时 12417772-1de6159a651fc702.png

12417772-1ba21a250055898e.png

interface.enqueue 发起Http

在调用apiService.getHttp() 接口的方法,发起Http请求时
其实就是通过动态代码在调用 --> InvocationHan.invoke()
而最终就是走到 --> return loadServiceMethod(method).invoke() 在跟进代码之后发现 12417772-b46616fb1827c138.png

-所以又回到了DafalutCallAdapterFactory 12417772-eeb5236638c991e3.png

  • 再看到OkHttpCall的方法 12417772-6ee36e30911eaca2.png

  • 这是真正的创建OkHttp的Call 12417772-b288fdb1a3efbf68.png

  • 拿到Okhttp的call后就可以网络请求了 12417772-16803211f4262491.png