Retrofit 是安卓上最流行的HTTP Client库之一,它因其出色的性能和简洁的实现广受开发者好评,那么现在就来看看它的实现原理。
使用方法
具体的使用方法,我在这里不再赘述,大家可以直接看它的官方文档 Retrofit官方文档,里面讲的非常简洁具体。
实现原理
在具体了解原理之前,我们先看看认真看完这一篇,不懂 Retrofit?不存在的(源码解析这篇文章中分享的Retrofit简易流程架构图:
下面我们来看看具体的代码实现。
1 | Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl, |
通过源码我发现,Retrofit的构造方法需要传入的参数较多,所以其采用了Builder模式来传入参数。
Retrofit Builder类
Builder类在创建Retrofit实例的过程中,主要需要传入一下几个参数:baseUrl、client、addConverterFactory、addCallAdapterFactory。下面依次来讲一下这些参数的意义。
baseUrl
:这个顾名思义,就是请求的基础Url;client
:这个是OkHttpClient的对象,也就是具体进行网络请求的对象。addConverterFactory
:这个就是生产Converter的工厂类,也就是生产在请求过程中对请求数据和回调数据进行转换的转换器的工厂类,主要是处理 ResponseBody, RequestBody 和 String类型的转化;addCallAdapterFactory
:这个是生产CallAdapter的工厂类。Call就是用来真正发起网络请求和接收回调的,而CallAdapter是将一个Call适配给另一个Call的适配器接口。对于后面两个工厂类可能还不是很清楚,这些会在后面讲具体实现中再讲它们是怎么用的。
Retrofit create方法
create方法是整个Retrofit的门面,一切后续操作都是从这里起步,那我们就来具体看看它的实现。
首先先看源码:
1 | @SuppressWarnings("unchecked") // Single-interface proxy creation guarded by parameter safety. |
开始的代码跟核心功能关系不大,先简单说说。首先是检查传入的是的是inteeface类。其次是根据需要创建所有接口的ServiceMethod,ServiceMethod是什么我们后面再说,而这个默认是关闭的,因为在创建ServiceMethod时是需要耗费时间和性能,所以一般不需要在一开始时就将所有请求的ServiceMethod就全部创建。接下来就是根据动态代理的方式来创建接口对象,这也是create方法的核心所在,那我们再来看看这里面做了什么。
首先如果是Object的方法就不管,其次如果是default 方法也不管。这里的default方法是java 8的新特性,在这里不做介绍。然后就是最关键的3行代码,接下啦我们就重点看看这几行代码。
loadServiceMethod(method)
在之前其实遇到过,创建接口的ServiceMethod。那什么是ServiceMethod呢?ServiceMethod就是根据接口的注解、传入参数等信息来创建的类,这里面包含着请求接口的请求方式、参数、请求header、url等等信息。除了这些以外,还有几个变量值得关注。
1.callFactory
它负责创建并执行Http请求。
2.callAdapter
它主要是把请求数据retrofit2.Call<T>
转化为相应的T
,而我们发现,ServiceMethod中的callAdapter其实就来自于一开始我们在初始化Retrofit时addCallAdapterFactory
所传入的工程类所创建。
3.responseConverter
它负责把服务器返回的数据(JSON、XML、二进制或者其他格式,由 ResponseBody 封装)转化为 T
类型的对象,同样,它也是Retrofit初始化时addConverterFactory
所传入的工程类所创建。
同时,Retrofit还对ServiceMethod进行了缓存,方便同一个接口调用时可以更快速。
然后是创建OkHttpCall。OkHttpCall
是OkHttp的包装类,所有OkHttp所需要的参数都需要在创建时传入。
最后是最关键的serviceMethod.callAdapter. adapt(okHttpCall)
。这里我用的是RxJavaCallAdapterFactory
这个工厂类,RxJavaCallAdapterFactory
的getCallAdapter
方法中对返回值的泛型类型进行了进一步检查,例如我们声明的返回值类型为Observable<List<Repo>>
,泛型类型就是List<Repo>
,这里对 retrofit2.Response
和retrofit2.adapter.rxjava.Result
进行了特殊处理,有单独的 adapter 负责进行转换,其他所有类型都由 SimpleCallAdapter 负责转换。所以CallAdapter
就是SimpleCallAdapter
,那就先来看看SimpleCallAdapter
中的adapt方法。
1 | @Override public <R> Observable<R> adapt(Call<R> call) { |
这里的实现方式也很简单,创建了一个Observable
,并由CallOnSubscribe
去实现逻辑,同时用OperatorMapResponseToBodyOrError
将retrofit2.Response
转化为声明的类型或者错误异常类型。
1 | @Override public void call(final Subscriber<? super Response<T>> subscriber) { |
CallOnSubscribe
中call的实现也很简洁,首先将okhttp3.Call
clone,因为它只能使用一次,所以每次都是新的clone进行请求。然后创建了RequestArbiter
,并将其设置给subscriber
。
在Subscriber
设置Producer
之后,Subscriber
会通过Producer
去请求数据,而Producer
请求到数据之后,再根据请求的量给Subscriber
发数据。
1 | @Override public void request(long n) { |
在Producer
的request
方法中,最主要的就是call.execute()
,并把值返回给下游。
总结
Retrofit
的分析就这些了,里面的代码确实非常漂亮,非常值得我们去学习。
推荐文章
认真看完这一篇,不懂 Retrofit?不存在的(源码解析
Retrofit分析-漂亮的解耦套路
Retrofit分析-经典设计模式案例
拆轮子系列:拆 Retrofit