Retrofit使用
Retrofit源码
主流程
- 源码查看入口
- Retrofit动态代理监听
- validateServiceInterface如何进行合法性校验和方法初始化
- 接着第2步和第3步看loadServiceMethod方法
这里的ConcurrentHashMap就是一个ConcurrentHashMap
- 看看ServiceMethod.parseAnnotations是如何创建ServiceMethod的
- HttpServiceMethod.paresAnnotations方法,获取ServiceMethod方法
- 两种kotlin的HttpServiceMethod(SuspendForResponse、SuspendForBody)的实现的内部原理
- HttpServiceMethod的执行
上面的第6/7步生成了一个ServiceMethod,ServiceMethod就是Retrofit桥接okhttp的关键代码。
在第2步中loadServiceMethod后会使用invoke方法执行请求,如下:
然后我们发现invoke是ServiceMethod中的方法,没有被子类实现。它内部实现如下:
也就是说invoke方法中会调用adapt方法,而这个adapt方法是需要子类实现的。所以我们去看adapt方法就可以了。
- 主流程结束
Retrofit是如何代理Okhttp的
- 首先使用一个OkHttpCall内部持有一个okhttp3.Call对象
2. OkhttpCall内部有executed方法和enqueue方法,内部会调用rawCall的相关方法实现代理okhttp3.Call
例如1,executed方法
而enqueue方法,内部会使用okhttp3.AsyncCall.enqueue进行异步请求,在相关的回调方法中响应回调数据。
这里的call的实际类型是OkHttpCall
CallAdapter.Factory是如何工作的
- 设置CallAdapterFactory的方法
- Retrofit是会有默认的CallAdapter.Factory 的,创建默认CallAdapter.Factory位置如下
3. HttpServiceMethod.parseAnnotations方法中获取使用CallAdapter.Factory
- 将callAdapter传入ServiceMethod中
- 我们分别看看CallAdapted和SuspendForResponse两种的实现
- CallAdapted
- SuspendForResponse
- 结束
Converter.Factory是如何工作的
- 构建请求的时候可以设置解析工厂类
- 然后会把解析工厂添加到Retrofit中
- 我们是如何使用converter工厂的
- 当执行HttpServiceMethod的invoke方法的时候会构建OkhttpCall
- 使用Converter解析返回结果
- 返回最终结果
默认的请求Converter
请求的默认Converter很简单,就一个,调用它的convert方法的时候,会直接把原装的RequestBody返回。
默认的响应Converter
响应的Converter有多种,如下图
总结
Retrofit在调用Retrofit.create创建Service接口实例的时候,会创建一个动态代理的监听。每次我们调用Service方法的时候就会回调动态代理的invoke方法。然后在动态代理的回调里面会经过多重逻辑处理后,调用loadServiceMethod创建ServiceMethod实例,ServiceMethod是一个抽象类,他有三个默认的实现类,分别是CallAdapted、SuspendForResponse、SuspendForBody,其中后两个用在suspend方法协程中的。
loadServiceMethod返回ServiceMethod后,会调用ServiceMethod的invoke方法,invoke方法是在父类ServiceMethod中的(需要强调的是,我们后面提到的OkHttpCall也是在这个方法中创建的),invoke方法中会调用adapt方法,adapt方法每个子类中都会实现。子类中会调用callAdapter.adapt获取响应Response,然后不同的ServiceMethod实现会执行自己的逻辑对Response处理,最终会返回一个Call对象,默认会返回retrofit2.OkHttpCall类型。
上一段中返回了一个OkHttpCall类型,然后我们会调用executed或enqueue同步或异步获取请求结果。例如调用enqueue的时候,OkHttpCall.enqueue内部会调用okhttp3.Call.enqueue执行请求,请求成功后会使用回调接口来回调数据(需要强调的是在OkHttpCall的enqueue和execute方法中都会调用parseResponse方法对响应进行处理,在parseResponse方法中会调用我们的converter对结果进行处理,然后包装成一个新的Response类型,新的Response中的body就是我们期望的返回类型。默认的Response.body是ResponseBody类型,如果使用GsonConverterFactory进行处理,Response.body类型就是我们期望的实体类类型)。