一、Retrofit本质流程和相关类
1.具体过程处理如下
- 通过解析 网络请求接口的注解 配置 网络请求参数
- 通过 动态代理 生成 网络请求对象
- 通过 网络请求适配器 将 网络请求对象 进行平台适配(平台包括:Android、Rxjava、Guava和java8)
- 通过 网络请求执行器 发送网络请求
- 通过 数据转换器 解析服务器返回的数据
- 通过 回调执行器 切换线程(子线程 ->>主线程)
- 用户在主线程处理返回结果
Retrofit在创建实例的时候,会封装对应的baseUrl、网络请求工厂okhttp3.Call.Factory callFactory(其实就是OkHttpClient对象)用来创建okhttp3.Call对象,在OkHttpCall.enqueue方法中、数据转换器集合List<Converter.Factory> converterFactories用来将对应的数据转换成需要的类型、回调执行器Executor callbackExecutor其实就是将网络请求从子线程切换到主线程(MainThreadExecutor)
在Retrofit的create方法中,会将对应的Service(其实就是interface)通过动态代理的方式返回一个实例,并且将Service中的方法封装成ServiceMethod对象,然后通过调用对应的CallAdapter的adapt方法获取到对应的Call实现类或者Observable对象,如果是RxJava2的方式,就是获取到Observable,如果是默认的方式,就是获取到对应的Call的实现类ExecutorCallbackCall;
使用RxJava2的方式的时候,其实就是通过返回的Observable去订阅观察者,将Observable的结果通知观察者,如果是异步的,其实RxJava2CallAdapter返回的就是CallEnqueueObservable,Observable.subscribe内部就会调用subscribeActual方法,对OkHttpCall这个请求做具体的调用。
2.Retrofit中的类
二、源码分析(基于Retrofit2.3.0版本)
本文源码解析是基于Retrofit2.3.0版本,后续版本略有变化,本文并未做对比。但大体逻辑类似
1.创建Retrofit实例
private static Retrofit buildRetrofit() {
return new Retrofit.Builder()
.baseUrl(getBaseUrl())
.client(getOkHttpClient())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())// Gson工厂,用于将请求结果返回并且解析成Bean对象
.build();
}
这部分我们分成六个步骤,即:
- new Retrofit
- Builder()
- baseUrl
- addCallAdapterFactory
- addConverterFactory
- build()
(1)步骤1:Retrofit类分析
分析Retrofit类,主要是分析其属性和用处
public final class Retrofit {
// 网络请求配置对象(对网络请求接口中方法注解进行解析后得到的对象)
// 作用:存储网络请求相关的配置,如网络请求的方法、数据转换器、网络请求适配器、网络请求工厂、基地址等
// TODO: 这里使用serviceMethodCache这个缓存的目的,其实主要也是反射比较耗费性能,为了节省性能
private final Map<Method, ServiceMethod<?, ?>> serviceMethodCache = new ConcurrentHashMap<>();
// 网络请求器的工厂
// 作用:生产网络请求器(Call)
// Retrofit是默认使用okhttp
final okhttp3.Call.Factory callFactory;
// 网络请求的BaseUrl地址
final HttpUrl baseUrl;
// 数据转换器工厂的集合
// 作用:放置数据转换器工厂
// 数据转换器工厂作用:生产数据转换器(converter)
final List<Converter.Factory> converterFactories;
// 网络请求适配器工厂的集合
// 作用:放置网络请求适配器工厂
// 网络请求适配器工厂作用:生产网络请求适配器(CallAdapter
final List<CallAdapter.Factory> adapterFactories;
// 回调方法执行器
final @Nullable Executor callbackExecutor;
// 标志位
// 作用:是否提前对业务接口中的注解进行验证转换的标志位
final boolean validateEagerly;
Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
List<Converter.Factory> converterFactories, List<CallAdapter.Factory> adapterFactories,
@Nullable Executor callbackExecutor, boolean validateEagerly) {
this.callFactory = callFactory;
this.baseUrl = baseUrl;
// unmodifiableList(list)近似于UnmodifiableList<E>(list)
// 作用:创建的新对象能够对list数据进行访问,但不可通过该对象对list集合中的元素进行修改
this.converterFactories = unmodifiableList(converterFactories); // Defensive copy at call site.
this.adapterFactories = unmodifiableList(adapterFactories); // Defensive copy at call site.
this.callbackExecutor = callbackExecutor;
this.validateEagerly = validateEagerly;
}
...// 这里省略其他代码,仅看属性和构造器
}
在Retrofit中,定义了网络请求器工厂、网络请求地址、数据转换器工厂、网络请求适配器工厂、回调方法执行器
CallAdapterFactory作用:
CallAdapterFactory是产生CallAdapter的,而CallAdapter是网络请求执行器Call的适配器
Call在Retrofit里默认是OkHttpCall
在Retrofit中提供了四种CallAdapterFactory: ExecutorCallAdapterFactory(默认)、GuavaCallAdapterFactory、Java8CallAdapterFactory、RxJavaCallAdapterFactory
而CallAdapterFactory的作用:将默认的网络请求执行器(OkHttpCall)转换成适合被不同平台来调用的网络请求执行器形式,如转换成RxJava2CallAdapterFactory
(2)建造者模式创建Retrofit实例
Retrofit.Builder静态内部类
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> adapterFactories = new ArrayList<>();
private @Nullable Executor callbackExecutor;
private boolean validateEagerly;
Builder(Platform platform) {
this.platform = platform;
// converterFactories是一个存放数据转换器Converter.Factory的数组
// 配置converterFactories即配置里面的数据转换器
// BuiltInConverters是一个内置的数据转换器工厂(继承Converter.Factory类)
// new BuiltInConverters()是为了初始化数据转换器
converterFactories.add(new BuiltInConverters());
}
// 在调用这个Builder构造器的时候,只是对平台、网络请求器的工厂等信息设置了默认值
public Builder() {
this(Platform.get());
}
...// 看Builder的构造器
}
从源码可以看出,Builder()其实就做了一件一件事,就是调用带Platform参数的构造器,并且初始化数据转换器。
Platform类
class Platform {
private static final Platform PLATFORM = findPlatform();
static Platform get() {
return PLATFORM;
}
private static Platform findPlatform() {
try {
// Class.forName(xxx.xx.xx)的作用:要求JVM查找并加载指定的类(即JVM会执行该类的静态代码段)
Class.forName("android.os.Build");
if (Build.VERSION.SDK_INT != 0) {
// 如果是Android平台,则返回一个Android对象
return new Android();
}
} catch (ClassNotFoundException ignored) {
}
try {
Class.forName("java.util.Optional");
return new Java8();
} catch (ClassNotFoundException ignored) {
}
return new Platform();
}
...
// 用于接收服务器返回数据后进行线程切换在主线程显示结果
static class Android extends Platform {
@Override public Executor defaultCallbackExecutor() {
// 返回一个默认的回调方法执行器
// 该执行器作用:切换线程(子->>主线程),并在主线程(UI线程)中执行回调方法
return new MainThreadExecutor();
}
@Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
if (callbackExecutor == null) throw new AssertionError();
// 创建默认的网络请求适配器工厂
// 该默认工厂生产的 adapter 会使得Call在异步调用时在指定的 Executor 上执行回调
// 在Retrofit中提供了四种CallAdapterFactory: ExecutorCallAdapterFactory(默认)、GuavaCallAdapterFactory、Java8CallAdapterFactory、RxJavaCallAdapterFactory
// 采用了策略模式
return new ExecutorCallAdapterFactory(callbackExecutor);
}
static class MainThreadExecutor implements Executor {
// 获取与Android 主线程绑定的Handler
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
// 该Handler是上面获取的与Android 主线程绑定的Handler
// 在UI线程进行对网络请求返回数据处理等操作。
handler.post(r);
}
}
}
}
从Platform.get()方法可以看出,这里是采用一个静态内部类对象的单例,platform是在Retrofit.Builder().build()中,用来初始化回调方法执行器和网络请求适配器工厂
(3)baseUrl()方法
Retrofit的静态内部类Builder的baseUrl方法
public Builder baseUrl(String baseUrl) {
checkNotNull(baseUrl, "baseUrl == null");
// 创建OkHttp3的HttpUrl对象,通过解析baseUrl创建
HttpUrl httpUrl = HttpUrl.parse(baseUrl);
if (httpUrl == null) {
throw new IllegalArgumentException("Illegal URL: " + baseUrl);
}
return baseUrl(httpUrl);
}
public Builder baseUrl(HttpUrl baseUrl) {
// 判断HttpUrl是否为空
checkNotNull(baseUrl, "baseUrl == null");
// 把URL参数分割成几个路径碎片
List<String> pathSegments = baseUrl.pathSegments();
// 检测最后一个碎片来检查URL参数是不是以"/"结尾
// 不是就抛出异常
if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
}
this.baseUrl = baseUrl;
return this;
}
这里是调用Builder.baseUrl方法,传入String类型的baseUrl,则会调用参数类型为HttpUrl的baseUrl对baseUrl进行封装,封装成一个HttpUrl对象
(4)addCallAdapterFactory方法
public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
adapterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
添加网络请求适配器工厂,该工厂会返回一个对应的Call对象,然后通过调用MainThreadExecutor的execute()方法,通过对应的Handler切换到主线程。在跟RxJava结合使用的时候,通过调用addCallAdapterFactory方法传入一个RxJava2CallAdapterFactory实例,用于返回一个RxJava2CallAdapter实例。
(5)addConverterFactory方法
public final class GsonConverterFactory extends Converter.Factory {
<-- 步骤1 -->
public static GsonConverterFactory create() {
// 创建一个Gson对象
return create(new Gson()); ->>步骤2
}
<-- 步骤2 -->
public static GsonConverterFactory create(Gson gson) {
// 创建了一个含有Gson对象实例的GsonConverterFactory
return new GsonConverterFactory(gson); ->>步骤3
}
private final Gson gson;
<-- 步骤3 -->
private GsonConverterFactory(Gson gson) {
if (gson == null) throw new NullPointerException("gson == null");
this.gson = gson;
}
}
GsonConverterFactory.create()是创建了一个含有Gson对象实例的GsonConverterFactory,并返回给addConverterFactory()
// 将上面创建的GsonConverterFactory放入到 converterFactories数组
// 在第二步放入一个内置的数据转换器工厂BuiltInConverters()后又放入了一个GsonConverterFactory
// 这是在build之前调用的addConverterFactory方法
public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
(6)Retrofit的静态内部类Builder的build()
public Retrofit build() {
<-- 配置网络请求执行器(callFactory)-->
okhttp3.Call.Factory callFactory = this.callFactory;
// 如果没指定,则默认使用okhttp
// 所以Retrofit默认使用okhttp进行网络请求
if (callFactory == null) {
callFactory = new OkHttpClient();
}
<-- 配置回调方法执行器(callbackExecutor)-->
Executor callbackExecutor = this.callbackExecutor;
// 如果没指定,则默认使用Platform检测环境时的默认callbackExecutor
// 即Android默认的callbackExecutor
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
<-- 配置网络请求适配器工厂(CallAdapterFactory)-->
List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
// 向该集合中添加了步骤2中创建的CallAdapter.Factory请求适配器(添加在集合器末尾)
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
// 请求适配器工厂集合存储顺序:自定义1适配器工厂、自定义2适配器工厂...默认适配器工厂(ExecutorCallAdapterFactory)
<-- 配置数据转换器工厂:converterFactory -->
// 在步骤2中已经添加了内置的数据转换器BuiltInConverters()(添加到集合器的首位)
// 在步骤4中又插入了一个Gson的转换器 - GsonConverterFactory(添加到集合器的首二位)
List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);
// 数据转换器工厂集合存储的是:默认数据转换器工厂( BuiltInConverters)、自定义1数据转换器工厂(GsonConverterFactory)、自定义2数据转换器工厂....
// 注:
//1. 获取合适的网络请求适配器和数据转换器都是从adapterFactories和converterFactories集合的首位-末位开始遍历
// 因此集合中的工厂位置越靠前就拥有越高的使用权限
// 最终返回一个Retrofit的对象,并传入上述已经配置好的成员变量
return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
callbackExecutor, validateEagerly);
}
2.创建网络请求接口实例
(1)如何创建网络请求接口的实例
不使用RxJava的创建方式
<-- 步骤1:在MainActivity创建接口类实例 -->
AccessApi NetService = retrofit.create(AccessApi.class);
<-- 步骤2:对发送请求的url进行封装,即生成最终的网络请求对象 -->
Call<JavaBean> call = NetService.getCall();
(2)分析Retrofit的create方法
Retrofit是通过外观模式&代理模式,使用create()方法创建网络请求接口的实例,同时通过网络请求接口里设置的注解进行了网络请求参数的配置。
public <T> T create(final Class<T> service) {
if (validateEagerly) {
// 判断是否需要提前验证,默认情况下是false
// 具体方法作用:
// 1. 给接口中每个方法的注解进行解析并得到一个ServiceMethod对象
// 2. 以Method为键将该对象存入LinkedHashMap集合中
// 特别注意:如果不是提前验证则进行动态解析对应方法(下面会详细说明),得到一个ServiceMethod对象,最后存入到LinkedHashMap集合中,类似延迟加载(默认)
eagerlyValidateMethods(service);
}
// 创建了网络请求接口的动态代理对象,即通过动态代理创建网络请求接口的实例 (并最终返回)
// 该动态代理是为了拿到网络请求接口实例上所有注解
return (T) Proxy.newProxyInstance(
service.getClassLoader(), // 动态生成接口的实现类
new Class<?>[] { service }, // 动态创建实例
new InvocationHandler() { // 将代理类的实现交给 InvocationHandler类作为具体的实现(下面会解释)
private final Platform platform = Platform.get();
// 在 InvocationHandler类的invoke()实现中,除了执行真正的逻辑(如再次转发给真正的实现类对象),还可以进行一些有用的操作
// 如统计执行时间、进行初始化和清理、对接口调用进行检查等。
@Override
public Object invoke(Object proxy, Method method, Object... args)
throws Throwable {
// 下面会详细介绍 invoke()的实现
// 即下面三行代码
ServiceMethod serviceMethod = loadServiceMethod(method);
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
在Retrofit.create函数中使用动态代理的方式,对网络请求接口创建实例,并且对网络请求接口中的注解方法做处理
eagerlyValidateMethods类
private void eagerlyValidateMethods(Class<?> service) {
Platform platform = Platform.get();
for (Method method : service.getDeclaredMethods()) {
if (!platform.isDefaultMethod(method)) { loadServiceMethod(method); }
// 将传入的ServiceMethod对象加入LinkedHashMap<Method, ServiceMethod>集合
// 使用LinkedHashMap集合的好处:lruEntries.values().iterator().next()获取到的是集合最不经常用到的元素,提供了一种Lru算法的实现
}
}
(3)看Retrofit#create中代理模式InvocationHandler类 # invoke()的具体实现:
new InvocationHandler() {
private final Platform platform = Platform.get();
@Override
public Object invoke(Object proxy, Method method, Object... args)
throws Throwable {
// 将详细介绍下面代码
// 关注点1
// 作用:读取网络请求接口里的方法,并根据前面配置好的属性配置serviceMethod对象
// 这里的method其实就是我们创建的Retrofit的对应接口Service中的每个方法
ServiceMethod serviceMethod = loadServiceMethod(method);
// 关注点2
// 作用:根据配置好的serviceMethod对象创建okHttpCall对象
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
// 关注点3
// 作用:调用OkHttp,并根据okHttpCall返回rejava的Observe对象或者返回Call
return serviceMethod.callAdapter.adapt(okHttpCall);
}
3.根据Retrofit.create创建Service的动态代理进行分析
(1)ServiceMethod serviceMethod = loadServiceMethod(method);
ServiceMethod loadServiceMethod(Method method) {
ServiceMethod result;
// 设置线程同步锁
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
// ServiceMethod类对象采用了单例模式进行创建
// 即创建ServiceMethod对象前,先看serviceMethodCache有没有缓存之前创建过的网络请求实例
// 若没缓存,则通过建造者模式创建 serviceMethod 对象
if (result == null) {
// 下面会详细介绍ServiceMethod生成实例的过程
// ServiceMethod其实就是根据网络请求接口中的每个方法创建对应的实例,这个实例保存了
// 网络请求时所需要的信息,包括网络请求的适配工厂,Response转换器,以及请求地址,
// 请求头,请求body,请求参数。而在ServiceMethod中的Builder类中,保存了一个请求方法
// 的注解解析数据、请求参数类型、请求方法里的参数的注解内容
result = new ServiceMethod.Builder(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
loadServiceMethod方法主要就是为了创建Service中的方法的ServiceMethod实例,并且缓存在一个Map集合中。而ServiceMethod实例中保存了请求这个接口的需要的信息,包括网络请求工厂、网络请求适配器、baseUrl、数据转换器、请求方式、相对地址、请求头、contentType、参数数据以及一些关于是否表达提交、文件提交等。
ServiceMethod类
public final class ServiceMethod {
final okhttp3.Call.Factory callFactory; // 网络请求工厂
final CallAdapter<?> callAdapter;
// 网络请求适配器工厂
// 具体创建是在new ServiceMethod.Builder(this, method).build()最后的build()中
// 下面会详细说明
private final Converter<ResponseBody, T> responseConverter;
// Response内容转换器
// 作用:负责把服务器返回的数据(JSON或者其他格式,由 ResponseBody 封装)转化为 T 类型的对象;
private final HttpUrl baseUrl; // 网络请求地址
private final String relativeUrl; // 网络请求的相对地址
private final String httpMethod; // 网络请求的Http方法
private final Headers headers; // 网络请求的http请求头 键值对
private final MediaType contentType; // 网络请求的http报文body的类型
private final ParameterHandler<?>[] parameterHandlers;
// 方法参数处理器
// 作用:负责解析 API 定义时每个方法的参数,并在构造 HTTP 请求时设置参数;
// 下面会详细说明
// 说明:从上面的成员变量可以看出,ServiceMethod对象包含了访问网络的所有基本信息
<-- ServiceMethod 类的构造函数 -->
// 作用:传入各种网络请求参数
ServiceMethod(Builder<T> builder) {
this.callFactory = builder.retrofit.callFactory();
this.callAdapter = builder.callAdapter;
this.responseConverter = builder.responseConverter;
this.baseUrl = builder.retrofit.baseUrl();
this.relativeUrl = builder.relativeUrl;
this.httpMethod = builder.httpMethod;
this.headers = builder.headers;
this.contentType = builder.contentType; .
this.hasBody = builder.hasBody; y
this.isFormEncoded = builder.isFormEncoded;
this.isMultipart = builder.isMultipart;
this.parameterHandlers = builder.parameterHandlers;
}
}
ServiceMethod的Builder类
public Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
// 获取网络请求接口方法里的注释
this.methodAnnotations = method.getAnnotations();
// 获取网络请求接口方法里的参数类型
this.parameterTypes = method.getGenericParameterTypes();
//获取网络请求接口方法里的注解内容
this.parameterAnnotationsArray = method.getParameterAnnotations();
}
ServiceMethod的Builder类的build方法
// 作用:控制ServiceMethod对象的生成流程
<-- 总结 -->
// 1. 根据返回值类型和方法标注从Retrofit对象的的网络请求适配器工厂集合和内容转换器工厂集合中分别获取到该方法对应的网络请求适配器和Response内容转换器;
// 2. 根据方法的标注对ServiceMethod的域进行赋值
// 3. 最后为每个方法的参数的标注进行解析,获得一个ParameterHandler<?>对象
// 该对象保存有一个Request内容转换器——根据参数的类型从Retrofit的内容转换器工厂集合中获取一个Request内容转换器或者一个String内容转换器。
public ServiceMethod build() {
// TODO:关注点1
callAdapter = createCallAdapter();
// 根据网络请求接口方法的返回值和注解类型,从Retrofit对象中获取对应的网络请求适配器
responseType = callAdapter.responseType();
// 根据网络请求接口方法的返回值和注解类型,从Retrofit对象中获取该网络适配器返回的数据类型
// TODO:关注点3
responseConverter = createResponseConverter();
// 根据网络请求接口方法的返回值和注解类型,从Retrofit对象中获取对应的数据转换器 -->关注点3
// 构造 HTTP 请求时,我们传递的参数都是String
// Retrofit 类提供 converter把传递的参数都转化为 String
// 其余类型的参数都利用 Converter.Factory 的stringConverter 进行转换
// @Body 和 @Part 类型的参数利用Converter.Factory 提供的 requestBodyConverter 进行转换
// 这三种 converter 都是通过“询问”工厂列表进行提供,而工厂列表我们可以在构造 Retrofit 对象时进行添加。
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
// 解析网络请求接口中方法的注解
// 主要是解析获取Http请求的方法
// 注解包括:DELETE、GET、POST、HEAD、PATCH、PUT、
// OPTIONS、HTTP、retrofit2.http.Headers、Multipart、FormUrlEncoded
// 处理主要是调用方法 parseHttpMethodAndPath(String httpMethod, String value, boolean hasBody)
// ServiceMethod中的httpMethod、hasBody、relativeUrl、relativeUrlParamNames域进行赋值
// 获取当前方法的参数数量
int parameterCount = parameterAnnotationsArray.length;
// 创建一个ParameterHandler数组,用于保存每个Method中注解值作为key以及参数值作为value的键值对数据
parameterHandlers = new ParameterHandler<?>[parameterCount];
for (int p = 0; p < parameterCount; p++) {
Type parameterType = parameterTypes[p];
Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
// 为方法中的每个参数创建一个ParameterHandler<?>对象并解析每个参数使用的注解类型
// 该对象的创建过程就是对方法参数中注解进行解析
// 这里的注解包括:Body、PartMap、Part、FieldMap、Field、Header、QueryMap、Query、Path、Url
parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
}
return new ServiceMethod<>(this);
}
ServiceMethod.Builder.build()中调用了createCallAdapter()方法
private CallAdapter<T, R> createCallAdapter() {
// 获取网络请求接口里方法的返回值类型
// 比如Retrofit采用默认的请求ExecutorCallAdapterFactory中的
// 则returnType是Call接口类型,其实实现类就是ExecutorCallbackCall
// 如果是采用RxJava,则returnType的返回值类型一般就是用Observable
// 参考RxJava2CallAdapterFactory和RxJava2CallAdapter
Type returnType = method.getGenericReturnType();
if (Utils.hasUnresolvableType(returnType)) {
throw methodError(
"Method return type must not include a type variable or wildcard: %s", returnType);
}
if (returnType == void.class) {
throw methodError("Service methods cannot return void.");
}
// 获取网络请求接口接口里的注解
// 比如@GET或者@POST等
Annotation[] annotations = method.getAnnotations();
try {
// 根据网络请求接口方法的返回值和注解类型,从Retrofit对象中获取对应的网络请求适配器
// 下面会详细说明retrofit.callAdapter()
return (CallAdapter<T, R>) retrofit.callAdapter(returnType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(e, "Unable to create call adapter for %s", returnType);
}
}
ServiceMethod.Builder.build()中调用了createCallAdapter()方法中返回Retrofit.callAdapter
public CallAdapter<?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
public CallAdapter<?> nextCallAdapter(CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
...
// 创建 CallAdapter 如下
// 遍历 CallAdapter.Factory 集合寻找合适的工厂(该工厂集合在第一步构造 Retrofit 对象时进行添加(第一步时已经说明))
// 如果最终没有工厂提供需要的 CallAdapter,将抛出异常
for (int i = start, count = adapterFactories.size(); i < count; i++) {
CallAdapter<?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
...
}
该方法的目的,就是从Retrofit中的网络请求适配器工厂集合中,获取到本网络请求ServiceMethod对应的网络请求适配器工厂。
ServiceMethod.Builder.build()中调用了createResponseConverter()方法
private Converter<ResponseBody, T> createResponseConverter() {
Annotation[] annotations = method.getAnnotations();
try {
// responseConverter 还是由 Retrofit 类提供 -->关注点4
return retrofit.responseBodyConverter(responseType, annotations);
} catch (RuntimeException e) {
throw methodError(e, "Unable to create converter for %s", responseType);
}
}
ServiceMethod.Builder.build()中调用了createResponseConverter()方法中返回调用Retrofit.responseBodyConverter方法
public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
return nextResponseBodyConverter(null, type, annotations);
}
public <T> Converter<ResponseBody, T> nextResponseBodyConverter(Converter.Factory skipPast,
int start = converterFactories.indexOf(skipPast) + 1;
for (int i = start, count = converterFactories.size(); i < count; i++) {
// 获取Converter 过程:(和获取 callAdapter 基本一致)
Converter<ResponseBody, ?> converter =
converterFactories.get(i).responseBodyConverter(type, annotations, this);
// 遍历 Converter.Factory 集合并寻找合适的工厂(该工厂集合在构造 Retrofit 对象时进行添加(第一步时已经说明))
// 由于构造Retroifit采用的是Gson解析方式,所以取出的是GsonResponseBodyConverter
// Retrofit - Converters 还提供了 JSON,XML,ProtoBuf 等类型数据的转换功能。
// 继续看responseBodyConverter() -->关注点5
}
ServiceMethod.Builder.build()中调用了createResponseConverter()方法中返回调用Retrofit.responseBodyConverter方法中,converterFactories.get(i)可以返回的是GsonConverterFactory,这里以GsonConverterFactory为例
Converter.Factory的实现类GsonConverterFactory的responseBodyConverter()
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type,
Annotation[] annotations, Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
// 根据目标类型,利用 Gson#getAdapter 获取相应的 adapter
return new GsonResponseBodyConverter<>(gson, adapter);
}
// 做数据转换时调用 Gson 的 API 即可。
final class GsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
private final Gson gson;
private final TypeAdapter<T> adapter;
GsonResponseBodyConverter(Gson gson, TypeAdapter<T> adapter) {
this.gson = gson;
this.adapter = adapter;
}
@Override
public T convert(ResponseBody value) throws IOException {
JsonReader jsonReader = gson.newJsonReader(value.charStream());
try {
return adapter.read(jsonReader);
} finally {
value.close();
}
}
}
从数据转换适配器的创建过程可以看出,通过从Retrofit中缓存的数据转换适配器工厂中取出对应的适配器工厂,并且创建对应的数据转换器,而GsonResponseConverter数据转换器的作用,就是通过Gson和JsonReader转换数据,具体转换参考Gson源码分析那篇
(2)OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
public class OkHttpCall {
private final ServiceMethod<T> serviceMethod; // 含有所有网络请求参数信息的对象
private final Object[] args; // 网络请求接口的参数
private okhttp3.Call rawCall; //实际进行网络访问的类
private Throwable creationFailure; //几个状态标志位
private boolean executed;
private volatile boolean canceled;
<--OkHttpCall构造函数 -->
public OkHttpCall(ServiceMethod<T> serviceMethod, Object[] args) {
// 传入了配置好的ServiceMethod对象和输入的请求参数
this.serviceMethod = serviceMethod;
this.args = args;
}
(3)return serviceMethod.callAdapter.adapt(okHttpCall);
将创建的OkHttpCall对象传给创建的ServiceMethod对象中对应的网络请求适配器工厂的adapt()
返回对象类型:Android默认的是Call<>;若设置了RxJavaCallAdapterFactory,返回的则是Observable<>
从上面部分createCallAdapter的时候,可以知道CallAdapter网络请求适配器是通过网络请求适配器工厂的get()方法获取到的
而默认的网络请求适配器工厂:ExecutorCallAdapterFactory
如果使用的是RxJava,则网络请求适配器工厂为:RxJava2CallAdapterFactory
不使用RxJava的情况-ExecutorCallAdapterFactory的get源码
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
final Type responseType = Utils.getCallResponseType(returnType);
return new CallAdapter<Object, Call<?>>() {
@Override public Type responseType() {
return responseType;
}
@Override public Call<Object> adapt(Call<Object> call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}
默认的网络请求方式,其网络请求适配器是在ExecutorCallAdapterFactory的get中采用返回的,而在return serviceMethod.callAdapter.adapt(okHttpCall);的时候,就是调用的这个get方法的CallAdapter实例,而这个CallAdapter实例的adapt方法其实就是返回的一个ExecutorCallbackCall对象,ExecutorCallbackCall是ExecutorCallAdapterFactory的静态内部类,是Call的接口实现类,实现了异步和同步调用方法,在创建ExecutorCallbackCall对象的时候,传入了callbackExecutor和call实例,call其实就是在Retrofit.create中动态代理中创建的OkHttpCall实例,而callbackExecutor其实就是在Platform实例创建之后,在Retrofit.Builder().build()方法中通过platform.defaultCallbackExecutor();赋值
在ExecutorCallbackCall中具体实现异步请求和同步请求的操作的,其实就是在Retrofit.create创建的OkHttpCall实例,并且通过Retrofit创建的callbackExecutor进行线程切换。ExecutorCallbackCall其实就是将OkHttpCall的委托给ExecutorCallbackCall,由ExecutorCallbackCall调用OkHttpCall执行操作。
使用RxJava的方式
如果是使用RxJava的方式,则是使用RxJava2CallAdapterFactory网络请求适配器工厂,其实get方法如下:
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
Class<?> rawType = getRawType(returnType);
if (rawType == Completable.class) {
// Completable is not parameterized (which is what the rest of this method deals with) so it
// can only be created with a single configuration.
return new RxJava2CallAdapter(Void.class, scheduler, isAsync, false, true, false, false,
false, true);
}
boolean isFlowable = rawType == Flowable.class;
boolean isSingle = rawType == Single.class;
boolean isMaybe = rawType == Maybe.class;
if (rawType != Observable.class && !isFlowable && !isSingle && !isMaybe) {
return null;
}
boolean isResult = false;
boolean isBody = false;
Type responseType;
if (!(returnType instanceof ParameterizedType)) {
String name = isFlowable ? "Flowable"
: isSingle ? "Single"
: isMaybe ? "Maybe" : "Observable";
throw new IllegalStateException(name + " return type must be parameterized"
+ " as " + name + "<Foo> or " + name + "<? extends Foo>");
}
Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType);
Class<?> rawObservableType = getRawType(observableType);
if (rawObservableType == Response.class) {
if (!(observableType instanceof ParameterizedType)) {
throw new IllegalStateException("Response must be parameterized"
+ " as Response<Foo> or Response<? extends Foo>");
}
responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
} else if (rawObservableType == Result.class) {
if (!(observableType instanceof ParameterizedType)) {
throw new IllegalStateException("Result must be parameterized"
+ " as Result<Foo> or Result<? extends Foo>");
}
responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
isResult = true;
} else {
responseType = observableType;
isBody = true;
}
return new RxJava2CallAdapter(responseType, scheduler, isAsync, isResult, isBody, isFlowable,
isSingle, isMaybe, false);
}
这部分就看最后的return,其实返回的就是一个RxJava2CallAdapter实例
RxJava2CallAdapter类
final class RxJava2CallAdapter<R> implements CallAdapter<R, Object> {
private final Type responseType;
private final @Nullable Scheduler scheduler;
private final boolean isAsync;
private final boolean isResult;
private final boolean isBody;
private final boolean isFlowable;
private final boolean isSingle;
private final boolean isMaybe;
private final boolean isCompletable;
RxJava2CallAdapter(Type responseType, @Nullable Scheduler scheduler, boolean isAsync,
boolean isResult, boolean isBody, boolean isFlowable, boolean isSingle, boolean isMaybe,
boolean isCompletable) {
this.responseType = responseType;
this.scheduler = scheduler;
this.isAsync = isAsync;
this.isResult = isResult;
this.isBody = isBody;
this.isFlowable = isFlowable;
this.isSingle = isSingle;
this.isMaybe = isMaybe;
this.isCompletable = isCompletable;
}
@Override public Type responseType() {
return responseType;
}
@Override public Object adapt(Call<R> call) {
// 执行网络请求,在这里是创建了Observable
// 然后就采用RxJava的观察者模式,CallEnqueueObservable其实就是一个被观察者
// 在Observable订阅观察者的时候,就会在subscribe内部调用
// CallEnqueueObservable的subscribeActual函数
// 在subscribeActual函数中调用了call.enqueue这个Http.Call的异步调用
Observable<Response<R>> responseObservable = isAsync
? new CallEnqueueObservable<>(call)
: new CallExecuteObservable<>(call);
Observable<?> observable;
if (isResult) {
observable = new ResultObservable<>(responseObservable);
} else if (isBody) {
observable = new BodyObservable<>(responseObservable);
} else {
observable = responseObservable;
}
// 如果是使用RxJava2的方式,则调用Observable的subscribeOn方法
// 其内部就调用了对应的Observable的subscribeActual方法
// 在Observable的subscribeActual方法内部就会调用对应的OkHttpCall的enqueue方法执行请求
if (scheduler != null) {
observable = observable.subscribeOn(scheduler);
}
if (isFlowable) {
return observable.toFlowable(BackpressureStrategy.LATEST);
}
if (isSingle) {
return observable.singleOrError();
}
if (isMaybe) {
return observable.singleElement();
}
if (isCompletable) {
return observable.ignoreElements();
}
return observable;
}
}
在这里返回的Observable其实就是通过是否异步来判断返回的CallEnqueueObservable或者CallExecuteObservable对象。
CallEnqueueObservable中的subscribeActual方法
CallExecuteObservable的subscribeActual方法与之类似,只不过CallExecuteObservable的subscribeActual方法内部是调用了OkHttpCall的execute()方法
final class CallEnqueueObservable<T> extends Observable<Response<T>> {
...
@Override protected void subscribeActual(Observer<? super Response<T>> observer) {
// Since Call is a one-shot type, clone it for each new observer.
Call<T> call = originalCall.clone();
CallCallback<T> callback = new CallCallback<>(call, observer);
observer.onSubscribe(callback);
call.enqueue(callback);
}
...
}
这里的Call,其实就是在Retrofit.create中的动态代理中创建的OkHttpCall对象,而在CallEnqueueObservable中的subscribeActual方法中,通过OkHttpCall对象调用enqueue执行请求,而在OkHttpCall.enqueue方法中,就会通过OkHttpCall的createRawCall()方法,通过okhttp3.Call.Factory callFactory对象创建okhttp3.Call对象,用来执行网络请求。所以okhttp3.Call.Factory callFactory目的就是用来创建OkHttp3.Call。而在OkHttpCall对象调用enqueue方法中,会转换返回结果,而解析返回结果其实就是通过ServiceMethod.toResponse方法,这个方法中转换返回结果其实就是借助转换器responseConverter
OkHttpCall.createRawCall()
private okhttp3.Call createRawCall() throws IOException {
Request request = serviceMethod.toRequest(args);
okhttp3.Call call = serviceMethod.callFactory.newCall(request);
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
Observable.subscribe方法
@SchedulerSupport(SchedulerSupport.NONE)
@Override
public final void subscribe(Observer<? super T> observer) {
ObjectHelper.requireNonNull(observer, "observer is null");
try {
observer = RxJavaPlugins.onSubscribe(this, observer);
ObjectHelper.requireNonNull(observer, "The RxJavaPlugins.onSubscribe hook returned a null Observer. Please change the handler provided to RxJavaPlugins.setOnObservableSubscribe for invalid null returns. Further reading: https://github.com/ReactiveX/RxJava/wiki/Plugins");
subscribeActual(observer);
} catch (NullPointerException e) { // NOPMD
throw e;
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
// can't call onError because no way to know if a Disposable has been set or not
// can't call onSubscribe because the call might have set a Subscription already
RxJavaPlugins.onError(e);
NullPointerException npe = new NullPointerException("Actually not, but can't throw other exceptions due to RS");
npe.initCause(e);
throw npe;
}
}
在RxJava2CallAdapter的adapt方法中,会创建Observable被观察者,如果是异步的,则CallEnqueueObservable对象,如果是同步的CallExecuteObservable对象。
而CallEnqueueObservable和CallExecuteObservable类都是Observable的子类,都重写了subscribeActual,subscribeActual方法是Observable调用subscribe方法订阅观察者的时候调用的。而具体的网络请求就是在subscribeActual中执行。
(4)总结
Retrofit采用了 外观模式 统一调用创建网络请求接口实例和网络请求参数配置的方法,具体细节是:
动态创建网络请求接口的实例(代理模式 - 动态代理)
创建 serviceMethod 对象(建造者模式 & 单例模式(缓存机制))
对 serviceMethod 对象进行网络请求参数配置:通过解析网络请求接口方法的参数、返回值和注解类型,从Retrofit对象中获取对应的网络请求的url地址、网络请求执行器、网络请求适配器 & 数据转换器。(策略模式)
对 serviceMethod 对象加入线程切换的操作,便于接收数据后通过Handler从子线程切换到主线程从而对返回数据结果进行处理(装饰模式)
(5)采用RxJava+Retrofit的总结
最终的网络请求,是在serviceMethod.callAdapter.adapt(okHttpCall);调用的时候,通过serviceMethod.callAdapter其实是在serviceMethod.Builder().build()的时候,调用createCallAdapter通过从Retrofit.callAdapter中,从adapterFactories获取到对应的CallAdapterFactory,然后再对应的CallAdapterFactory的get方法中返回对应的CallAdapter,然后再调用CallAdapter的adpt函数,在这里进行最终的网络请求返回Observable,在RxJava2CallAdapter的adpt函数中会通过判断是否是异步返回对应的Observable
Observable<Response<R>> responseObservable = isAsync
? new CallEnqueueObservable<>(call)
: new CallExecuteObservable<>(call);
在拿到这个Observable之后,CallEnqueueObservable的subscribeActual会调用Call的对应请求方法,如果是同步的就调用call.execute();如果是异步的就调用你call.enqueue(callback);
这个调用在Observable.subscribe订阅观察者的时候会触发,这样就执行了网络请求。
创建ServiceMethod对象,是为了配置对应的数据,比如网络请求工厂、网络请求适配器、Response内容转换器、请求地址、请求方法、请求头、ContentType、请求参数、方法注解和参数注解
(6)采用普通方式的总结
如果不是用的RxJava,那么网络请求工厂去获取网络请求适配器的时候,是用ExecutorCallAdapterFactory这个工厂,其get函数返回一个CallAdapter匿名内部类实现,然后这个CallAdapter的adpt函数会返回ExecutorCallbackCall对象,这个对象就是OkHttp3.Call的子类
如果是返回的Okhttp3.Call,那么就需要手动的触发execute或者enqueue
4.执行网络请求
这里针对OkHttpCall的使用源码做一定的分析
不管是使用普通方式还是RxJava方式,网络请求均是使用OkHttpCall来实现。
Retrofit默认使用OkHttp,即OkHttpCall类(实现了 retrofit2.Call<T>接口)
OkHttpCall提供两种网络请求方式:
同步请求:OkHttpCall.execute()
异步请求:OkHttpCall.enqueue()
比如采用非RxJava的形式实现网络请求的时候,Retrofit.create方法会返回一个默认的Call接口实现类,而这个默认的接口实现类对象其实就是ExecutorCallbackCall对象,是ExecutorCallAdapterFactory的内部类,是对OkHttpCall的封装代理,
static final class ExecutorCallbackCall<T> implements Call<T> {
// 线程切换执行器,默认的是MainThreadExecutor对象,
// 是咋Platform类中的
final Executor callbackExecutor;
// 代理OkHttpCall类
final Call<T> delegate;
...
(1)同步请求OkHttpCall.execute()
其实采用非RxJava2对象的话,则是调用ExecutorCallbackCall的execute(),而ExecutorCallbackCall的execute()其实就是调用了OkHttpCall的execute()
这是OkHttpCall的execute()方法
@Override public Response<T> execute() throws IOException {
okhttp3.Call call;
// 设置同步锁
synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
if (creationFailure != null) {
if (creationFailure instanceof IOException) {
throw (IOException) creationFailure;
} else {
throw (RuntimeException) creationFailure;
}
}
call = rawCall;
if (call == null) {
try {
// 步骤1:创建一个OkHttp的Request请求对象 -->关注1
call = rawCall = createRawCall();
} catch (IOException | RuntimeException e) {
creationFailure = e;
throw e;
}
}
}
if (canceled) {
call.cancel();
}
// 步骤2:调用OkHttpCall的execute()发送网络请求(同步)
// 步骤3:解析网络请求返回的数据parseResponse() -->关注2
return parseResponse(call.execute());
}
针对上面的这三步,做进一步的分析
call = rawCall = createRawCall();
创建Http请求对象,其实就是Okhttp3.Call实现类对象,其实就是OkHttp3的RealCall对象。
private okhttp3.Call createRawCall() throws IOException {
// 从ServiceMethod的toRequest()返回一个Request对象
Request request = serviceMethod.toRequest(args);
// 根据serviceMethod和request对象创建 一个okhttp3.Request
okhttp3.Call call = serviceMethod.callFactory.newCall(request);
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
return parseResponse(call.execute());
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
// 这里就是Retrofit执行网络请求之后返回的结果,返回的body其实是stream
ResponseBody rawBody = rawResponse.body();
// Remove the body's source (the only stateful object) so we can pass the response along.
rawResponse = rawResponse.newBuilder()
.body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
.build();
int code = rawResponse.code();
if (code < 200 || code >= 300) {
try {
// Buffer the entire body to avoid future I/O.
ResponseBody bufferedBody = Utils.buffer(rawBody);
return Response.error(bufferedBody, rawResponse);
} finally {
rawBody.close();
}
}
if (code == 204 || code == 205) {
rawBody.close();
return Response.success(null, rawResponse);
}
ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
try {
// 内部调用responseConverter.convert(body);
T body = serviceMethod.toResponse(catchingBody);
return Response.success(body, rawResponse);
} catch (RuntimeException e) {
// If the underlying source threw an exception, propagate that rather than indicating it was
// a runtime exception.
catchingBody.throwIfCaught();
throw e;
}
}
在使用Retrofit的时候需要特别注意:
ServiceMethod几乎保存了一个网络请求所需要的数据
发送网络请求时,OkHttpCall需要从ServiceMethod中获得一个Request对象
解析数据时,还需要通过ServiceMethod使用Converter(数据转换器)转换成Java对象进行数据解析。其实Retrofit的OkHttpCall就是在create中创建的OkHttpCal对象
(2)异步请求:OkHttpCall.enqueue()
发送请求过程
步骤1:对网络请求接口的方法中的每个参数利用对应ParameterHandler进行解析,再根据ServiceMethod对象创建一个OkHttp的Request对象
步骤2:使用OkHttp的Request发送网络请求;
步骤3:对返回的数据使用之前设置的数据转换器(GsonConverterFactory)解析返回的数据,最终得到一个Response<T>对象
步骤4:进行线程切换从而在主线程处理返回的数据结果
OkHttpCall.enqueue
如果是异步请求,则需要先调用ExecutorCallbackCall的enqueue方法,然后在ExecutorCallbackCall的enqueue方法中调用OkHttpCall的enqueue方法,而这里的callback回调,就是在ExecutorCallbackCall中实现的时候使用了callbackExecutor进行线程切换。
先看ExecutorCallbackCall的enqueue()方法
@Override public void enqueue(final Callback<T> callback) {
checkNotNull(callback, "callback == null");
delegate.enqueue(new Callback<T>() {
@Override public void onResponse(Call<T> call, final Response<T> response) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
if (delegate.isCanceled()) {
// Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation.
callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
} else {
callback.onResponse(ExecutorCallbackCall.this, response);
}
}
});
}
@Override public void onFailure(Call<T> call, final Throwable t) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
callback.onFailure(ExecutorCallbackCall.this, t);
}
});
}
});
}
再看OkHttpCall的enqueue方法
@Override public void enqueue(final Callback<T> callback) {
checkNotNull(callback, "callback == null");
okhttp3.Call call;
Throwable failure;
synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
call = rawCall;
failure = creationFailure;
if (call == null && failure == null) {
try {
call = rawCall = createRawCall();
} catch (Throwable t) {
failure = creationFailure = t;
}
}
}
if (failure != null) {
callback.onFailure(this, failure);
return;
}
if (canceled) {
call.cancel();
}
call.enqueue(new okhttp3.Callback() {
@Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse)
throws IOException {
Response<T> response;
try {
response = parseResponse(rawResponse);
} catch (Throwable e) {
callFailure(e);
return;
}
callSuccess(response);
}
@Override public void onFailure(okhttp3.Call call, IOException e) {
try {
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable t) {
t.printStackTrace();
}
}
private void callFailure(Throwable e) {
try {
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable t) {
t.printStackTrace();
}
}
private void callSuccess(Response<T> response) {
try {
callback.onResponse(OkHttpCall.this, response);
} catch (Throwable t) {
t.printStackTrace();
}
}
});
}
这里如果是不使用RxJava,则采用的是默认的ExecutorCallAdapterFactory网络请求适配器工厂,那么就会先调用ExecutorCallbackCall的enqueue方法,然后在获取到请求结果之后通过callbackExecutor进行网络请求的线程切换。
而ExecutorCallbackCall的enqueue方法中调用了delegate.enqueue方法,这个方法其实就是调用的OkHttpCall的enqueue方法。ExecutorCallbackCall其实就是对OkHttpCall的一个封装,采用委托模式。
使用RxJava2的网络请求,在网络请求适配器的adapt方法时有请求的不同:
而如果是使用了RxJava2CallAdapterFactory工厂,那么在Retrofit.create方法中就会通过动态代理返回RxJava2CallAdapter的adapt方法,而在RxJava2CallAdapter的adapt方法中,会通过判断是否是异步来执行不同的网络请求,返回Observable结果:
Observable<Response<R>> responseObservable = isAsync
? new CallEnqueueObservable<>(call)
: new CallExecuteObservable<>(call);
如果是异步的,就会创建CallEnqueueObservable对象
然后通过判断是否是需要返回的body还是result来封装成不同的Observable
if (isResult) {
observable = new ResultObservable<>(responseObservable);
} else if (isBody) {
observable = new BodyObservable<>(responseObservable);
} else {
observable = responseObservable;
}
这里的Observable是一个被观察者对象,因为使用了RxJava2的时候,会将Observable被观察者对象订阅一个观察者,调用Observable的subscribe方法,在这个方法里调用被观察者的subscribeActual方法。
这时,就会优先调用ResultObservable的subscribeActual方法,
@Override protected void subscribeActual(Observer<? super Result<T>> observer) {
upstream.subscribe(new ResultObserver<T>(observer));
}
然后在这个方法内部调用CallEnqueueObservable的subscribeActual方法,
@Override protected void subscribeActual(Observer<? super Response<T>> observer) {
// Since Call is a one-shot type, clone it for each new observer.
Call<T> call = originalCall.clone();
CallCallback<T> callback = new CallCallback<>(call, observer);
observer.onSubscribe(callback);
call.enqueue(callback);
}
在这里执行异步请求任务,然后将结果返回给观察者。