在使用 Retrofit 时, 需要创建 Retrofit 的实例, 定义一个网络请求接口并为接口中的方法添加注解, 接着通过动态代理生成网络请求对象, 关于动态代理的介绍可以查看《Android 小知识 - 剖析 Retrofit 前的预备知识 (静态代理与动态代理)》, 在 Retrofit 中会去解析在网络请求接口中的注解, 并配置网络请求参数, 通过动态代理拦截生成网络请求对象.
内部通过网络请求适配器将网络请求对象进行平台适配, 比如 Android 或 Java8, 接着通过网络请求执行器发送网络请求, 这个网络请求执行器就是 Call, 这个 Call 就是对 OkHttp 的一个封装, 底层还是使用 OkHttp 来发送请求的, 服务端返回的数据会经过数据转换器进行解析, 在《Android 小知识 - Retrofit 框架的介绍以及使用方式》章节中, 使用的是 GsonConverter 来解析数据, 最终转换成 Java 对象, 接着通过回调执行器切换线程, 最后客户端在主线程处理返回的结果.
- Retrofit retrofit = new Retrofit.Builder()
- .baseUrl("http://icould.glh/")
- .addConverterFactory(GsonConverterFactory.create())
- .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
- .build();
上面创建 Retrofit 的实例在《Android 小知识 - Retrofit 框架的介绍以及使用方式》中已经讲过了, 创建 Retrofit 实例采用的是构建者模式, 构建者模式可以将一个对象的复杂构建与表示进行分离, 我们进入 Retrofit 的源码.
- public final class Retrofit {
- private final Map<Method, ServiceMethod<?, ?>> serviceMethodCache = new ConcurrentHashMap<>();
- final okhttp3.Call.Factory callFactory;
- final HttpUrl baseUrl;
- final List<Converter.Factory> converterFactories;
- final List<CallAdapter.Factory> callAdapterFactories;
- final @Nullable Executor callbackExecutor;
- final boolean validateEagerly;
- ...
- }
在具体分析源码前, 我们有必要了解 Retrofit 的几个成员变量.
serviceMethodeCache 是一个 LinkedHashMap 对象, 它的 key 值是 Method, 对应的就是 Http 的请求方法, value 是 ServiceMethod,ServiceMethod 是对网络请求接口内的方法的注解进行解析封装后的对象.
callFactory 是网络请求工厂, 在 Retrofit 内默认的网络请求工厂采用的就是 OkHttpClient.
baseUrl 就是网络请求的 URL 的基地址, baseUrl 加上网络请求接口中通过注解定义的相对地址, 就组成了一个完整的请求地址.
converterFactories 是数据转换器工厂集合, 内部存放的是数据转换器工厂, 而数据转换器工厂是用于生产数据转换器, 数据转换器的作用就是对请求网络之后的 Response 进行转换, 通过 GsonConverter 转换成 Java 对象.
adapterFactories 是网络请求适配器工厂集合, 内部存放的是网络请求适配器工厂, 网络适配器工厂是用生产网络适配器, 网络请求适配器的作用就是将 Call 对象转换成其他类型, 如果需要支持 RxJava, 就可以将 Call 对象转换成 RxJava 平台的 Call.
callbackExecutor 是一个线程池, 用于执行回调的线程池.
validateEagerly 是一个标志位, 是否需要立即解析接口中的方法, 具体后面进行讲解, 这里先有个印象.
Retrofit 的 7 个成员变量介绍完了, 接着进入 Retrofit 的 Builder 类:
- public final class Retrofit {
- ...
- public static final class Builder {
- private final Platform platform;
- private @Nullable okhttp3.Call.Factory callFactory;
- private HttpUrl baseUrl;
- private final List<Converter.Factory> converterFactories = new ArrayList<>();
- private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>();
- private @Nullable Executor callbackExecutor;
- private boolean validateEagerly;
- ...
- }
- ...
- }
Builder 类是 Retrofit 的静态内部类, 成员变量 platform 表示 Retrofit 适配的平台, 主要包括 Android 和 Java 8, 默认情况下使用的是 Android 平台; callFactory 表示请求网络的 OkHttp 的工厂, 默认情况下使用 OkHttp 来完成请求; baseUrl 表示网络请求的 URL, 通过 Builder 的 baseUrl 方法传入一个 String 类型的 url, 再将 String 类型的 url 转换成 HttpUrl;converterFactories 是数据转换器工厂的集合; callAdapterFactories 是网络请求适配器工厂的集合; callbackExecutor 用执行异步回调; validateEagerly 是一个标志位, 表示是否需要立即解析接口中的方法, 在使用动态代理时对网络请求接口中方法的注解进行解析时会用到这个标志位.
- public final class Retrofit {
- ...
- public static final class Builder {
- public Builder() {
- this(Platform.get());
- }
- ...
- }
- ...
- }
在 Builder 的构造函数中通过 this 传入一个 Platform 类型, 也就是适配的平台, 进入 Platform 的 get 方法:
- private static final Platform PLATFORM = findPlatform();
- static Platform get() {
- return PLATFORM;
- }
- private static Platform findPlatform() {
- try {
- Class.forName("android.os.Build");
- if (Build.VERSION.SDK_INT != 0) {
- return new Android();
- }
- } catch (ClassNotFoundException ignored) {
- }
- try {
- Class.forName("java.util.Optional");
- return new Java8();
- } catch (ClassNotFoundException ignored) {
- }
- return new Platform();
- }
Platform 是一个单例类, 通过 findPlatform 方法来初始化实例, 在静态方法 get 中返回了 PLATFORM 静态变量, 而 PLATFORM 静态变量的初始化是在 findPlatform 方法中完成的, 在 findPlatform 方法中先是通过反射加载 "android.os.Build" 类, 接着返回一个 Android 平台的 Platform 对象, 我们看一下这个 Android 对象.
- static class Android extends Platform {
- @Override public Executor defaultCallbackExecutor() {
- return new MainThreadExecutor();
- }
- @Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
- if (callbackExecutor == null) throw new AssertionError();
- return new ExecutorCallAdapterFactory(callbackExecutor);
- }
- static class MainThreadExecutor implements Executor {
- private final Handler handler = new Handler(Looper.getMainLooper());
- @Override public void execute(Runnable r) {
- handler.post(r);
- }
- }
- }
在 defaultCallbackExecutor 中返回一个 MainThreadExecutor 对象, 表示默认的回调方法执行器, 这个执行器的作用是从子线程切换到主线程, 看下面 MainThreadExecutor 实现了 Executor, 是一个线程池, 并且内部在创建 Handler 时传入的是主线程的 Looper, 通过 Looper.getMainLooper() 获取主线程 Looper, 也就是说这个 Executor 和主线程已经绑定了. 继续看 Android 类中的 defaultCallAdapterFactory 方法, 它表示创建一个默认的网络请求适配器工厂的执行器, 在 Call 对象执行异步请求时, 需要一个执行器将异步请求后的数据传递到主线程, defaultCallAdapterFactory 放内传入的就是异步请求时进行数据传递所需要的执行器.
在 Builder 的无参构造方法内调用了有参构造方法:
- Builder(Platform platform) {
- this.platform = platform;
- }
将创建好的 Android 平台 Platform 对象赋值给 Builder 类的成员变量 platform.
Builder 的相关成员变量的初始化已经介绍完毕, 接着看看它的 build 方法:
- public Retrofit build() {
- ...
- // 创建 OkHttpClient 的工厂
- okhttp3.Call.Factory callFactory = this.callFactory;
- if (callFactory == null) {
- callFactory = new OkHttpClient();
- }
- // 创建主线程执行器
- Executor callbackExecutor = this.callbackExecutor;
- if (callbackExecutor == null) {
- callbackExecutor = platform.defaultCallbackExecutor();
- }
- // 添加网络请求适配器工厂
- List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
- callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
- // 添加数据转换器工厂
- List<Converter.Factory> converterFactories =
- new ArrayList<>(1 + this.converterFactories.size());
- converterFactories.add(new BuiltInConverters());
- converterFactories.addAll(this.converterFactories);
- // 创建 Retrofit 实例
- return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
- unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
- }
build 方法中的注释已经很详细了, 判断 callFactory 是否为空, 如果为空, 默认创建 OkHttpClient, 这也说明了 Retrofit 内部默认是使用 OkHttp 来进行网络请求的; callbackExecutor 默认通过 platform 的 defaultCallbackExecutor 方法获取执行器, 这里的 platform 默认是 Android 平台, 在前面讲解 Android 平台类时, 就已经知道了它的 defaultCallbackExecutor 方法返回的是主线程的执行器, 最终数据就是通过主线程的执行器发送到主线程的.
创建完主线程的执行器后, 添加网络请求适配器工厂, 这里添加了 Android 平台的 defaultCallAdapterFactory 方法传入主线程的执行器, 这样在进行异步请求后可以通过主线程的执行器进行数据传递.
最后就是添加数据转换器工厂, 默认添加了一个 BuiltInConverters 对象, BuiltInConverters 表示的是内置的默认的数据转换器工厂.
来源: https://juejin.im/post/5bdac4286fb9a0226924b215