前言
在Android的异步网络请求中,一般都会使用到一些优秀的开源库来简化网络请求与线程切换过程,Retrofit+RxJava也是时下最热门的搭配,对与Retrofit的学习,也给我带来的极大的收获,特别是了解其中的一些套路,会给自己的开发带来很大的启示。
1.主线任务
在具体分析之前,采用单步调试的方式先把主线拎出来,理解大致的运行过程:
在开始分析之前,有两个需要明白的地方:
1.Retrofit只能算是一个加强版的API管理库,具体的网络请求是依赖内部的OkHttp来实现的。
2. Retrofit是通过动态代理解析注解来构建Request发起请求的。
从图中可以看到:
1.在发起请求的时候,Retrofit会尝试去加载一个ServiceMethod,这个ServiceMethod的作用是封装了Retrofit的三大核心功能:CallAdapter、Converter和从注解解析出的Request(具体过程后面会提到)。当然,由于每次调用ApiService接口中的方法时都会通过动态代理进行拦截,然后执行上图的一整套过程,所以为了避免每次都去花费过多的时间去创建ServiceMathod,就需要将它缓存到一个Map中,以减少开销。
2.在拿到ServiceMethod过后,需要将它交给OkHttpCall,它其实就相当于是一个OkHttp的包装类,可以用来执行具体的请求,这里只是将ServiceMethod和接口方法中的参数传了进去,给OkHttpCall的成员变量赋值,暂时没有做什么具体的工作。
3.接下来就是将OkHttpCall交给CallAdapter进行适配的,这里就要分情况进行分析了,如果指定了常用的RxJavaCallAdapter,自然就会将OkHttpCall转化为Observable类型的Call;如果没有制定具体的CallAdapter,则会将使用默认的Call(也就是ExecutorCallbackCall,后面会提到);当然,这里完全可以由开发者更具业务需求,自定义一个CallAdapter,这也是我们可以扩展的地方。
4.经过上一步的操作,用于请求的Call也得到了,就该使用OkHttpClient来执行真正的网络请求了。
5.在请求执行完,服务器返回结果之后就会使用Converter来讲结果转换为我们需要的数据格式。
6.最终,采用RxJava或者直接使用Handler切换到到主线程,数据也在这个时候回调到了主线程。
2.理解三个大的模块的逻辑
我认为学习Retrofit主要需要从三个大的方向去入手:Request的构建方式、CallAdapter的创建或注入时机、Converter的创建或注入时机。下面就分别跟着源码来进行一番探索:
2.1 使用动态代理+注解+反射的方式来构建Request
在第一次使用Retrofit的时候,肯定会被这种配置请求方式的形式吸引到,没想到还有注解这种操作..
以常用的GET方式为例,来看看究竟是怎么将这些注解和接口方法转化为请求需要的Call的。
public interface ApiService {
@GET("top250")
Call<MovieBeen> getMovie(@Query("start") int start, @Query("count") int count);
}
在配置Request信息的时候只需要在在接口中使用注解即可,使用的时候直接调用:
ApiService apiService = retrofit.create(ApiService.class);
这一句话就可以拿到ApiServerce的实例,往往外层简单的东西,内层都不简单,进入create() 方法一探究竟:
public <T> T create(final Class<T> service) {
···