上一篇 站在巨人的肩膀上 – Retrofit源码解析(一) 主要是从Retrofit使用的基本API角度,去理清源码中大致的流程,可以说Retrofit是对OkHttp框架做了非常完美的封装,使用了大量的设计模式,使得Retrofit成为了一个简单易上手的网络请求框架. 这一篇主要解决上一篇留下来的疑问.
Retrofit源码基于版本2.4.0
1.ServiceMethod.Builder类的build函数,调用createCallAdapter函数是怎么获取到callAdapter的?
从createCallAdapter函数出发,调用到Retrofit类的callAdapter函数
private CallAdapter<T, R> createCallAdapter() {
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.");
}
Annotation[] annotations = method.getAnnotations();
try {
//noinspection unchecked
//遍历 存放网络请求适配器工厂的集合callAdapterFactories,找到合适的网络请求适配器工厂并返回
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);
}
}
callAdapter函数调用nextCallAdapter函数,主要遍历callAdapterFactories这个存放网络请求适配器工厂的集合,获取跟网络请求函数返回值Call<List< Contributor>>相关的网络请求适配器工厂,那callAdapterFactories是在哪里存入适配器工厂? 存入了哪些适配器工厂?
public final class Retrofit {
public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
//
public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
checkNotNull(returnType, "returnType == null");
checkNotNull(annotations, "annotations == null");
//遍历存放网络请求适配器工厂的集合callAdapterFactories,找到合适的网络请求适配器工厂调用其get函数并返回CallAdapter实例
int start = callAdapterFactories.indexOf(skipPast) + 1;
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
...省略无关代码
}
}
callAdapterFactories是在Retrofit的构造函数中赋值的, 而Retrofit是通过Build模式创建的, 看Retrofit.Builder类的build函数
public final class Retrofit {
public static final class Builder {
public Retrofit build() {
...省略部分无关代码
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
//将MainThreadExecutor装载进ExecutorCallAdapterFactory工厂实例里,并将工厂实例添加进 网络请求适配器工厂的集合里
callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
...省略部分无关代码
//Collections.unmodifiableList()函数是将集合转化成只读的
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
//添加网络请求适配器
public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
callAdapterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
}
}
看到callAdapterFactories存入开发者自行添加进去的网络请求适配器工厂,还存入该平台默认的网络请求适配器工厂,此处是Android平台,对应的网络请求适配器工厂为ExecutorCallAdapterFactory, 还记得我们在创建Retrofit时调用了.addCallAdapterFactory(RxJavaCallAdapterFactory.create()),所以此处自行添加的网络请求适配器工厂是RxJavaCallAdapterFactory.
现在也就找到callAdapterFactories是在Retrofit.Builder的build函数中存入适配器工厂的,存入了两个适配器工厂,分别是ExecutorCallAdapterFactory和RxJavaCallAdapterFactory.
那上面说的 “获取跟网络请求函数返回值Call<List< Contributor>>相关的网络请求适配器工厂”,获取到的就应该是ExecutorCallAdapterFactory和RxJavaCallAdapterFactory其中之一
在Retrofit类的nextCallAdapter函数中,通过遍历callAdapterFactories集合,取出网络请求适配器工厂并调用自身的get函数,我们看下ExecutorCallAdapterFactory和RxJavaCallAdapterFactory这两个类的get函数
public final class RxJavaCallAdapterFactory extends CallAdapter.Factory {
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
Class<?> rawType = getRawType(returnType);
boolean isSingle = rawType == Single.class;
boolean isCompletable = rawType == Completable.class;
//请求函数的返回值必须是 Observable或Single或Completable
//否则返回null
if (rawType != Observable.class && !isSingle && !isCompletable) {
return null;
}
if (isCompletable) {
return new RxJavaCallAdapter(Void.class, scheduler, isAsync, false, true, false, true);
}
}
}
由于我们在上篇文章中写的网络请求函数的返回值是 “Call<List< Contributor>>”, 那RxJavaCallAdapterFactory的get函数中getRawType(returnType)拿到的Class类型就是Call,不满足判断条件, 所以此处会返回null, 因此不是RxJavaCallAdapterFactory
final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
@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;
}
//这里传入的call = OkHttpCall实例,callbackExecutor = MainThreadExecutor实例
@Override public Call<Object> adapt(Call<Object> call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}
}
ExecutorCallAdapterFactory类的get函数中,通过getRawType获取到的是Call类型,满足条件,那么满足适配器工厂条件的就是ExecutorCallAdapterFactory类,其get函数中创建了CallAdapter的匿名内部类并返回,那此处的匿名内部类实例就是ServiceMethod.Builder类的createCallAdapter函数中retrofit.callAdapter( )获取到的值,也就是在ServiceMethod.Builder类的build函数调用createCallAdapter函数返回的就是这个匿名内部类
2.ServiceMethod.Builder类的build函数,调用createResponseConverter函数是怎么生成responseConverter的?
这里生成的responseConverter的代码流程跟上面1类似
从createResponseConverter函数出发,调用到Retrofit类的nextResponseBodyConverter函数
private Converter<ResponseBody, T> createResponseConverter() {
Annotation[] annotations = method.getAnnotations();
try {
//遍历 存放数据转换器工厂的集合converterFactories,找到合适的数据转换器工厂并返回
return retrofit.responseBodyConverter(responseType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(e, "Unable to create converter for %s", responseType);
}
}
public final class Retrofit {
public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
return nextResponseBodyConverter(null, type, annotations);
}
public <T> Converter<ResponseBody, T> nextResponseBodyConverter(
@Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
checkNotNull(type, "type == null");
checkNotNull(annotations, "annotations == null");
//遍历 存放数据转换器工厂的集合converterFactories,找到合适的数据转换器工厂并返回
int start = converterFactories.indexOf(skipPast) + 1;
for (int i = start, count = converterFactories.size(); i < count; i++) {
Converter<ResponseBody, ?> converter =
converterFactories.get(i).responseBodyConverter(type, annotations, this);
if (converter != null) {
//noinspection unchecked
return (Converter<ResponseBody, T>) converter;
}
}
...省略无关代码
}
}
在nextResponseBodyConverter函数中,主要遍历converterFactories这个存放数据转换器工厂的集合,获取跟网络请求函数返回值Call<List< Contributor>>相关的数据转换器工厂,那converterFactories在哪里存入数据转换器工厂? 存入了哪些数据转换器工厂?
converterFactories是在Retrofit的构造函数中赋值的, 而Retrofit是通过Build模式创建的, 看Retrofit.Builder类的build函数
public final class Retrofit {
public static final class Builder {
public Retrofit build() {
//...省略无关代码
List<Converter.Factory> converterFactories =
new ArrayList<>(1 + this.converterFactories.size());
//将默认的数据转换器装载进工厂实例里,添加数据转换器工厂进集合里
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
//Collections.unmodifiableList()函数是将集合转化成只读的
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
//添加数据转化器工厂
public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
}
}
看到converterFactories存入开发者自行添加进去的数据转换器工厂,还存入该平台默认的数据转换器工厂BuiltInConverters类的实例, 还记得我们在创建Retrofit时调用了.addConverterFactory(GsonConverterFactory.create()),所以此处自行添加的数据转换器工厂是GsonConverterFactory.
现在也就找到converterFactories是在Retrofit.Builder的build函数中存入转换器工厂的,存入了两个数据转换器工厂,分别是BuiltInConverters和GsonConverterFactory.
那上面说的 “获取跟网络请求函数返回值Call<List< Contributor>>相关的数据转换器工厂”,获取到的就应该是BuiltInConverters和GsonConverterFactory其中之一
在Retrofit类的nextResponseBodyConverter函数中,通过遍历converterFactories集合,取出数据转换器工厂并调用自身的responseBodyConverter函数,我们看下BuiltInConverters和GsonConverterFactory这两个类的responseBodyConverter函数
final class BuiltInConverters extends Converter.Factory {
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
if (type == ResponseBody.class) {
return Utils.isAnnotationPresent(annotations, Streaming.class)
? StreamingResponseBodyConverter.INSTANCE
: BufferingResponseBodyConverter.INSTANCE;
}
if (type == Void.class) {
return VoidResponseBodyConverter.INSTANCE;
}
return null;
}
}
此处的type就是根据网络请求函数返回值Call<List< Contributor>> 获取到的响应数据类型,即type 等于java.util.List<com.example.retrofit.SimpleService$Contributor>,所以BuiltInConverters类的responseBodyConverter函数经过判断会返回null,显然不是这个系统默认的数据转换器工厂
public final class GsonConverterFactory extends Converter.Factory {
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonResponseBodyConverter<>(gson, adapter);
}
}
根据type等于java.util.List<com.example.retrofit.SimpleService$Contributor>,返回的应该是GsonConverterFactory这个数据转换器工厂,在其responseBodyConverter函数中返回GsonResponseBodyConverter类的实例,GsonResponseBodyConverter是负责将响应数据转化为开发者指定的Java类
因此,在ServiceMethod.Builder类的build函数调用createResponseConverter函数返回的就是GsonResponseBodyConverter类的实例, 即responseConverter就是GsonResponseBodyConverter类的实例
3.OkHttpCall类的createRawCall函数中的call的具体实现类是哪个? 内部怎么实现的?
final class OkHttpCall<T> implements Call<T> {
private okhttp3.Call createRawCall() throws IOException {
okhttp3.Call call = serviceMethod.toCall(args);
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
}
createRawCall函数中的call是通过调用ServiceMethod类的toCall函数生成的,看toCall函数
final class ServiceMethod<R, T> {
okhttp3.Call toCall(@Nullable Object... args) throws IOException {
//...省略无关代码
//callFactory = OkHttpClient,该OkHttpClient是在Retrofit.Buidler的build函数中进行设置值的
//所以这里的okhttp3.Call来源于OkHttp.RealCall类的实例
return callFactory.newCall(requestBuilder.build());
}
}
callFactory是在ServiceMethod的构造函数中被赋值,其值来自于Retrofit类,回到Retrofit.Builder类的build函数中
public final class Retrofit {
public static final class Builder {
public Retrofit build() {
//开发者是否传入OkHttpClient实例,未传入则创建
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
return new Retrofit(callFactory, baseUrl,
unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor,
validateEagerly);
}
public Builder callFactory(okhttp3.Call.Factory factory) {
this.callFactory = checkNotNull(factory, "factory == null");
return this;
}
}
}
callFactory变量就是在此处被初始化的, 在创建Retrofit时,如果开发者未传入okhttp3.Call.Factory类的实现实例, 则会赋予系统默认的OkHttpClient,所以callFactory实际就是OkHttpClient实例.
接着回到ServiceMethod类的toCall函数,callFactory.newCall() 不就等于OkHttpClient.newCall(), 对OkHttp框架熟悉的话,是不是觉得似曾相似
public class OkHttpClient implements Cloneable, Factory, okhttp3.WebSocket.Factory {
public Call newCall(Request request) {
return RealCall.newRealCall(this, request, false);
}
}
那么OkHttpCall类的createRawCall函数中的call也就是此处生成的RealCall实例. 从这可以看出,OkHttpCall类是通过OkHttp框架来发起异步/同步的请求
4.OkHttpCall类的enqueue函数和execute函数中调用的parseResponse(rawResponse)函数,内部是怎么解析响应数据的?
final class OkHttpCall<T> implements Call<T> {
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
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 {
//将响应数据转化为 网络请求函数中定义的返回类型
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;
}
}
}
看上面的代码,核心在serviceMethod.toResponse这一句, 接着往下看
final class ServiceMethod<R, T> {
R toResponse(ResponseBody body) throws IOException {
return responseConverter.convert(body);
}
}
这里的responseConverter不就是上面第2个问题中获取到的GsonResponseBodyConverter类的实例,而GsonResponseBodyConverter内部是用了Gson框架来解析数据.
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 {
T result = adapter.read(jsonReader);
if (jsonReader.peek() != JsonToken.END_DOCUMENT) {
throw new JsonIOException("JSON document was not fully consumed.");
}
return result;
} finally {
value.close();
}
}
}
5.retrofit类create函数中的serviceMethod.adapt是怎么返回OkHttpCall类的,内部是怎么实现的?
public final class Retrofit {
public static final class Builder {
public <T> T create(final Class<T> service) {
//检查网络请求接口类是不是接口,有没继承其他接口 等
Utils.validateServiceInterface(service);
//判断是否需要提前缓存ServiceMethod对象, validateEagerly默认为false
if (validateEagerly) {
eagerlyValidateMethods(service);
}
// 使用动态代理模式拿到 网络请求接口类的函数的注解、函数参数、函数返回值等相关信息
// 返回接口调用实例Call,其实这个Call是ExecutorCallbackCall类(Retrofit的Call的实现类)的实例,在后面的代码中能看到
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();
@Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
throws Throwable {
// If the method is a method from Object then defer to normal invocation.
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
//ServiceMethod接口负责存 网络请求接口类的函数的注解、函数参数、函数返回值等相关信息
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
//OkHttpCall是对Retrofit.Call的实现,实际该类主要用到OkHttp.Call(rawCall这个变量) 来进行enqueue、execute请求
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
//这里实际上返回的是ExecutorCallbackCall类(Retrofit的Call的实现类)的实例,看后面的代码
return serviceMethod.adapt(okHttpCall);
}
});
}
}
}
跟进去ServiceMethod类的adapt函数
final class ServiceMethod<R, T> {
T adapt(Call<R> call) {
return callAdapter.adapt(call);
}
}
adapt函数是调用了callAdapter对象的adapt函数,有没觉得这个callAdapter蛮熟悉的,这不就是上面第1点的callAdapter,它的值就是ExecutorCallAdapterFactory类中get函数中创建的匿名内部类
final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
@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;
}
//这里传入的call = OkHttpCall实例,callbackExecutor = MainThreadExecutor实例
@Override public Call<Object> adapt(Call<Object> call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}
}
那么retrofit类create函数中的serviceMethod.adapt()拿到的就是此处的ExecutorCallbackCall的实例,那ExecutorCallbackCall这个类又有什么用呢? 这里多提一个问题,ExecutorCallbackCall是Retrofit框架中很重要的一个类,往下看
6.从上面第5点知道retrofit类create函数中的serviceMethod.adapt()返回的是ExecutorCallbackCall类,这个类有什么作用?
final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
static final class ExecutorCallbackCall<T> implements Call<T> {
final Executor callbackExecutor;
final Call<T> delegate;
//这里传入的delegate = OkHttpCall实例,callbackExecutor = MainThreadExecutor实例
ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
this.callbackExecutor = callbackExecutor;
this.delegate = delegate;
}
@Override public void enqueue(final Callback<T> callback) {
checkNotNull(callback, "callback == null");
//这里的delegate = OkHttpCall实例
//OkHttpCall是对Retrofit.Call的实现,实际该类主要用到OkHttp.Call(rawCall这个变量) 来进行enqueue、execute请求
delegate.enqueue(new Callback<T>() {
@Override public void onResponse(Call<T> call, final Response<T> response) {
//callbackExecutor = MainThreadExecutor, 主要从子线程切换到主线程并返回响应结果
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);
}
});
}
});
}
@Override public boolean isExecuted() {
return delegate.isExecuted();
}
@Override public Response<T> execute() throws IOException {
//这里的delegate = OkHttpCall实例
return delegate.execute();
}
@Override public void cancel() {
delegate.cancel();
}
@Override public boolean isCanceled() {
return delegate.isCanceled();
}
@SuppressWarnings("CloneDoesntCallSuperClone") // Performing deep clone.
@Override public Call<T> clone() {
return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone());
}
@Override public Request request() {
return delegate.request();
}
}
}
看上面的代码和注释,ExecutorCallAdapterFactory类主要做了两件事
-
结合代码和注释,调用OkHttpCall类来发起请求,从上面第3点了解到,OkHttpCall类是通过OkHttp框架来发起异步/同步的请求,因此ExecutorCallbackCall类间接调用了OkHttp框架来发起异步/同步的请求
-
MainThreadExecutor把子线程切换到主线程, 将请求OkHttp框架返回的服务端响应数据回调返回