一、Retrofit的大致使用
|
|
二、Retrofit的工作原理
从使用上看,Retrofit就是充当了一个适配器(Adapter)的角色:将一个Java接口翻译成一个Http请求,然后用OkHttp去发送这个请求。其中,翻译的过程是通过Java的动态代理完成的。
三、源码分析
(一)动态代理类的创建过程
|
|
1)Retrofit#create:
|
|
在这里创建了动态代理类Proxy.newProxyInstance并返回了一个RxHttpService接口对象,当后面service执行方法时,将被动态代理拦截,进入newProxyInstance()方法内部,里面创建了一个InvocationHandler类。InvocationHandler类是代理类和委托类之间的中间类,主要工作是:
|
|
2)Retrofit#loadMethodHandler:
|
|
Retrofit内部维护了一个method对应的Map表,这里将每一个method都封装成MethodHandler类(委托类),再将method和MethodHandler作为键值对存入Map表;所以调用代理类Proxy,实际上就是调用委托类MethodHandler的invoke,具体的实现逻辑都在MethodHandler中。
(二)委托类MethodHandler的具体工作
1)MethodHandler类
|
|
MethodHandler是系统为定义的Service接口中的每一个method创建的一个具体执行类,通过调用其invoke函数,来执行具体的请求逻辑。在create()中主要做三件事:
- createCallAdapter():在retrofit中找到一个合适的callAdapter。
- createResponseConverter():在retrofit中找到一个合适的ResponseConverter。
- RequestFactoryParser.parse():通过解析返回类型和method的对应注解获得主要的请求信息。
MethodHandler主要包含四个变量:
|
|
Call.Factory:————就是OkHttpClient
RequestFactory:包含了HTTP请求的Url、Header信息、MediaType、Method以及RequestAction数组
CallAdapter:HTTP请求返回数据的类型
ResponseConverter:对返回数据进行转换的类型转换器
接下来具体看每个变量的创建:
2)Retrofit#callAdapter
在MethodHandler#create中直接通过createCallAdapter()创建一个CallAdapter
|
|
但实际上createCallAdapter()内部是调用Retrofit#callAdapter并传入method的注解创建CallAdapter的
|
|
adapterFactorie是Retrofit上的一个链表,保存了所有的CallAdapter.Factory,通过遍历获取相应的CallAdapter。而在我们创建Retrofit的时候呢,写过
|
|
由此,我们可以在最外层定义我们需要的CallAdapterFactory,否则将加载系统默认的CallAdapterFactory。
3)Retrofit#responseBodyConverter
在MethodHandler#create中通过createResponseConverter()获取一个ResponseConverter,但实际上也是通过Retrofit实现的。
|
|
Retrofit内同样维护了一个converterFactories的链表,保存了所有的Converter.Factory,通过responseType和method的注解(annotations)获取链表中符合条件的ResponseConverter。而我们在创建Retrofit的时候,设置了
|
|
由此,加载了GsonConverterFactory这个响应体的转换器,通过responseType找到response对应的Object,再使用annotations对该Object进行校验,返回合适的ResponseConverter。
4)RequestFactory
我们知道,RxHttpService的每一个method对应的主要请求信息都在method对应的注解上,而RequestFactoryParser就是根据method对应的注解及返回类型进行相应解析,并将解析出的信息都保存在一个RequestFactory中,好让OkHttpCall正式发起访问时再将RequestFactory整合成一个Request。
|
|
|
|
解析的主要工作由parseMethodAnnotations(responseType)和parsePameters(retrofit)完成。最后通过toRequestFactory()使用创造者模式创建一个RequestFactory对象,包含method、url、headers、contentType、其他表单信息等内容。
5)MethodHandler#invoke
|
|
动态代理创建的代理类使用InvokeHandler调用委托类的invoke来实现一个具体的方法。而委托类是系统根据method创建的MethodHandler,在创建过程中会通过Retrofit获取对应callAdapter和responseConverter的引用,并通过解析responseType和method对应的注解创建一个RequestFactory。在委托类MethodHandler调用自身的invoke函数后,invoke又继续调用callAdapter#adapt函数,生成一个OkHttpCall对象。OkHttpCall是对OkHttp里面的Call的封装,将所有的操作都委托给该Call进行操作,获取响应后OkHttp.Call由将结果传回给OkHttpCall,OkHttpCall使用responseConverter.convert()将结果转化成对应对象,在通过Callback将结果对象和结果一并传到最外层,交给我们使用。
6)OkHttpCall
|
|
这里主要方法是createRawCall()、call.enqueue()和parseResponse()。
|
|
首先requestFactory根据args参数创建一个Request,然后okHttpClient再根据request创建一个call。注意,这里的callFactory其实就是OkHttpClient,在创建Retrofit的时候,我们设置过
|
|
再看Retrofit#client方法:
|
|
至此,OkHttp.Call已经创建完成了,在后面call.enqueue()就是由OkHttp去完成网络请求,然后通过OkHttp的回调Callback#onResponse得到响应后通过parseResponse()将结果转为对象,再通过OkHttpCall的回调Callback将结果对象和结果一并传到最上层。
OkHttpCall#execute过程同理。