主要参考文章:
对应的源码版本如下:
'com.squareup.retrofit2:retrofit:2.5.0'
// 并且引入了 GsonConverter 与 RxJavaCallAdapter
'com.squareup.retrofit2:converter-gson:2.5.0'
'com.squareup.retrofit2:adapter-rxjava:2.5.0'
辅助讲解用的示例代码为 Kotlin 版本的。
首先需要弄清楚这段代码的作用,即 retrofit 是怎么实例化的。
val retrofit = Retrofit.Builder()
.baseUrl("http://fy.iciba.com/")
// 设置 CallAdapterFactory 到 Retrofit 的 callAdapterFactories 中
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
// 设置 ConverterFactory 到 Retrofit 的 converterFactories 中
.addConverterFactory(GsonConverterFactory.create())
// 通过构建者模式实例出 retrofit
.build()
Builder 的无参构造方法如下:
public Builder() {
this(Platform.get());
}
这里,涉及到了一个平台(Platform
) 的概念。
class Platform {
private static final Platform PLATFORM = findPlatform();
// get() 方法会根据当前环境得到对应的 Platform
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
,即 Android
、Java8
,以及 Platform
自身(另外两种继承自它)。因此,可以知道 Retrofit 不仅仅是能在 Android 中使用,在正常的 Java8 中也能够使用。
static class Android extends Platform {
...
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
// 得到默认的 CallAdapterFactories
@Override List<? extends CallAdapter.Factory> defaultCallAdapterFactories(
@Nullable Executor callbackExecutor) {
if (callbackExecutor == null) throw new AssertionError();
ExecutorCallAdapterFactory executorFactory = new ExecutorCallAdapterFactory(callbackExecutor);
return Build.VERSION.SDK_INT >= 24
? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
: singletonList(executorFactory);
}
// 得到默认的 ConverterFactories
@Override List<? extends Converter.Factory> defaultConverterFactories() {
return Build.VERSION.SDK_INT >= 24
? singletonList(OptionalConverterFactory.INSTANCE)
: Collections.<Converter.Factory>emptyList();
}
// MainThreadExecutor 的作用就是切换回主线程,其具体的实现就是利用主线程的 Handler
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
其中,又只有 Android 涉及到实际的 defaultCallbackExecutor
,具体类型为 MainThreadExecutor
,因为只有 Android 中有 UI 线程的概念,而 defaultCallbackExecutor
的作用就是为了切换线程,通过 execute()
方法,就可以切换了。
而其他的 defaultCallbackExecutor
为 null
之后,对于 Retrofit.Builder#build()
的源码如下:
public Retrofit build() {
// 1、必须要设置 baseUrl
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
// 2、 callFactory 默认使用 okhttp 的 OkHttpClient
// 或者使用 Builder#callFactory() 方法传递自定义的
callFactory = new OkHttpClient();
}
// 3、callbackExecutor 用来将回调传递到 UI 线程
// 当然 platform.defaultCallbackExecutor() 默认为 null
// 只有 Android 类型的 Platform 才会有一个实际的 MainThreadExecutor
// 而 MainThreadExecutor 就是利用主线程的 handler 来实现将回调传递到 UI 线程
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
// 4、adapterFactories 主要用于存储 CallAdapter.Factory,
// 而 CallAdapter 是对原始的 OkHttpCall 实例进行转化用的
// 如在使用 RxJavaCallAdapterFactory 的时候,就会得到 RxJavaCallAdapter,可以把 OkHttpCall 实例转换为 Observable
// 或者默认的 CallAdapter,可以转换为 ExecutorCallbackCall,即通常在接口方法定义的返回值类型 retrofit2.Call<> (ExecutorCallbackCall 实现了 retrofit2.Call 接口 )
// 实际上,与其是说转换,用包装更为准确,即将 OkHttpCall 包装为 Observable、ExecutorCallbackCall 等
// (具体的原因第二部分的讲解)
// Make a defensive copy of the adapters and add the default Call adapter.
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
// 5、converterFactories 主要用于存储转化数据的对象
// 如常用的 addConverterFactory(GsonConverterFactory.create())。
// 而 Converter 的作用就是把 Call 转换为 Call
// 注意,这里不是把 Call 中的 okhttp3.ResponseBody 转换为 R,因为 okhttp3.ResponseBody 也是经过转换来的;
// 而是将 okhttp 请求中得到的原始的 okhttp3.ResponseBody 转换为目标 R 类型。
// 只不过在 Android 的 Retrofit 中默认是将原始的 okhttp3.ResponseBody 实例转换为新的 okhttp3.ResponseBody 实例
// 虽然类型没变,但还是经过了 Retrofit 的 Converter 的转换
// (后面第二部分的第 4 点会说到)
// Make a defensive copy of the converters.
List<Converter.Factory> converterFactories = new ArrayList<>(
1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());
// Add the built-in converter factory first. This prevents overriding its behavior but also
// ensures correct behavior when using converters that consume all types.
// 保证最开始的是 BuiltInConverters
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
// 添加平台默认的 ConverterFactories
converterFactories.addAll(platform.defaultConverterFactories());
// 通过设置的参数 new 出 Retrofit 实例
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
在上述源码中,主要涉及到几个点:
(1) 从注释 2 处可以知道,Retrofit 默认是借助 OkHttp 来实现网络请求的,而且实际上,也仅且用 OkHttp 来实现,因为 Retrofit.Builder
有且只存在两个成员方法,client(OkHttpClient client)
和 RcallFactory(okhttp3.Call.Factory factory)
用来配置其成员变量 callFactory
,而 okhttp3.Call.Factory
就是 okhttp3 用来生成 okhttp3.Call
的。
(2) 对于注释 4,涉及到了 CallAdapter
,其作用就是为了把 Call
转换为 X
,因为最原始的返回值就是 retrofit2.Call
类型的,如下:
@GET
fun test(): Call<ResponseBody>
// 使用了 RxJavaCallAdapterFactory 后,就可以转换为 Observable
(3) 对于注释 5,涉及到了 Converter,其作用了是为了把 Call
转换为指定类型 Call
,如使用 GsonConverterFactory
,就可以将 ResponseBody
转换为实体类。
在最后,就会通过配置的参数 new 出 Retrofit
实例。
在通过 Retrofit.Builder
构建出 retrofit
实例之后,就会使用 retrofit.create(XXXService::class.java)
在方法来得到一个定义了方法的接口的实例。
如:
interface TestService {
@GET(...)
fun testMethod(): Call<ResponseBody>
}
val testService = retrofit.create(TestService::class.java)
val call = testService.testMethod()
call.enqueue(object : Callback<ResponseBody> {
override fun onFailure(call: Call<ResponseBody>, t: Throwable) {}
override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {}
})
Retrofit#create()
方法源码如下:
public <T> T create(final Class<T> service) {
// 检查 service 是不是有效的,即必须是一个接口,且不能继承自其他接口
Utils.validateServiceInterface(service);
if (validateEagerly) {
// 实现加载缓存 XXXService 中定义的方法
eagerlyValidateMethods(service);
}
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();
private final Object[] emptyArgs = new Object[0];
@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);
}
// 1
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}
});
}
从源码中可以知道,create()
方法会返回关于 XXXService
的动态代理对象。以 TestService
为例,则通过 create()
方法(实际上是通过 Proxy.newProxyInstance()
)来得到 TestService
的动态代理对象,通过该代理对象,就能够间接调用 TestService
中定义的方法。
当调用 TestService
的 testMethod()
方法时,最终会调用 InvocationHandler
的 invoke()
方法,该方法有 3 个参数,第一个是代理对象,第二个是调用的方法实例(即 testMethod()
方法实例),第三个是方法的参数。
正常情况下,是会执行到注释 1 处的。比如 testMethod()
,该方法不是 Object
类的,也不是默认方法,因此会通过 Retrofit#loadServiceMethod()
方法得到一个对应的 ServiceMethod
对象实例,然后执行其 invoke()
方法并返回 testMethod()
方法定义的返回值类型的返回值,因为 fun testMethod(): Call
,即返回一个 retrofit2.Call
类型的 call 实例。
简答的说,通过该代理对象,就实现了调用 TestService#testMethod()
方法,得到对应的返回值 call(retrofit2.Call
类型),然后就可实现同步或者异步请求了。
ServiceMethod<?> loadServiceMethod(Method method) {
ServiceMethod<?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
// 解析 method 中的注解,生成对应的 ServiceMethod(实际上是 HttpServiceMethod,后面会说)
result = ServiceMethod.parseAnnotations(this, method);
serviceMethodCache.put(method, result);
}
}
return result;
}
loadServiceMethod() 方法会根据传递进来的 method
实例,返回对应的 ServiceMethod
实例,如果还不存在,则会先通过 ServiceMethod.parseAnnotations
生产该实例,并缓存到 serviceMethodCache
(ConcurrentHashMap
类型)中,然后再返回。
在上面讲到,会通过 ServiceMethod.parseAnnotations()
方法得到 method
对应的 ServiceMethod
实例。实际上,ServiceMethod
是一个抽象类,真正的是 HttpServiceMethod
实例。
abstract class ServiceMethod<T> {
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
// 1、解析 method 的注解(包括用于注释方法与参数的),得到对应的 requestFactory
// requestFactory 用于创建 okhttp 需要的 request 请求
RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
// 得到 method 定义的返回类型,看是否符合要求,即不能包含类型变量和通配符,且返回值不能为空类型
Type returnType = method.getGenericReturnType();
if (Utils.hasUnresolvableType(returnType)) {
throw methodError(method,
"Method return type must not include a type variable or wildcard: %s", returnType);
}
if (returnType == void.class) {
throw methodError(method, "Service methods cannot return void.");
}
// 2、根据传入的 requestFactory 得到对应的 HttpServiceMethod 实例
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
abstract T invoke(Object[] args);
}
从注释 2 可以知道,loadServiceMethod()
方法实际上得到的是 HttpServiceMethod
实例。
并且,在前面说到,通过代理对象来调用接口中定义的方法,实际上会调用 HttpServiceMethod
的 invoke()
方法。
loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
而 invoke()
的源码如下:
@Override ReturnT invoke(Object[] args) {
return callAdapter.adapt(
new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
}
可以看到,在里面会利用 callAdapter
来将传入的 OkHttpCall
转换为 ReturnT
类型并返回,而 ReturnT
类型就是我们在接口 XXXService
中定义的方法的返回类型,如 retrofit2.Call
、rx.Observable
等。
至于 callAdapter
是怎么来的,后面会说。
在上一点的注释 1 处,有提到要解析 method 的注释(就像下面的 @GET
、@Path
等),来生成一个 requestFactory 对象(来用于构建请求的 request)。
@GET(...)
fun testMethod(@Path("path1") path: String): Call<ResponseBody>
需要注意的是,是有两种注释,一种是用来修饰方法本身的,一种是用来修饰方法的参数的。
// RequestFactory.parseAnnotations()
static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
return new Builder(retrofit, method).build();
}
因为注释有两种,因此实际上也是分两步来解析的。即下面源码中的注释 1、2。
// RequestFactory.Builder#build()
RequestFactory build() {
// 1、解析注释方法的注解
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
...
int parameterCount = parameterAnnotationsArray.length;
parameterHandlers = new ParameterHandler<?>[parameterCount];
// 遍历所有参数
for (int p = 0; p < parameterCount; p++) {
// 2、解析用于注释参数的注解,进一步来说,是调用 parseParameterAnnotation() 方法,
parameterHandlers[p] = parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p]);
}
...
return new RequestFactory(this);
}
private ParameterHandler<?> parseParameter(
int p, Type parameterType, @Nullable Annotation[] annotations) {
ParameterHandler<?> result = null;
if (annotations != null) {
// 遍历所有注释参数的注解,得到对应的 ParameterHandler
for (Annotation annotation : annotations) {
ParameterHandler<?> annotationAction =
parseParameterAnnotation(p, parameterType, annotations, annotation);
...
result = annotationAction;
}
return result;
}
其中,ParameterHandler
,即参数处理器,作用就是用来处理被不同注释注解的参数,具体的如下几种子类。分别针对参数进行处理成 request
中对应的内容,如 header
等。
其实,讲到这里,对于 Retrofit2 的浅层次工作原理就大致说清楚了,即利用动态代理,以及运行时注解,来对接口中定义的方法进行处理。
下面还需要进一步探究一下,具体是怎么实现网络请求的,以及 CallAdapter、Converter 是怎样起作用的。
前面说到,通过 HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory)
会得到 HttpServiceMethod
实例:
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
// 1、根据 ReturnT 得到对应的 callAdapter
CallAdapter<ResponseT, ReturnT> callAdapter = createCallAdapter(retrofit, method);
//得到例如 Call 中原始的 ResponseBody 类型需要转换成的目标类型 R
Type responseType = callAdapter.responseType();
...
// 2、根据 ResponseT 得到对应的 responseConverter,即用于将 ResponseBody 转换为 ResponseT 的 converter
Converter<ResponseBody, ResponseT> responseConverter =
createResponseConverter(retrofit, method, responseType);
// 3、callFactory 默认为 OkHttpClient
// 在 Retrofit.Builder#build() 方法中设置的
okhttp3.Call.Factory callFactory = retrofit.callFactory;
// 4、最终返回 HttpServiceMethod 实例
return new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);
}
(1) 对于注释 1 处,有:
private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
Retrofit retrofit, Method method) {
// 得到方法的返回类型
Type returnType = method.getGenericReturnType();
// 得到注解方法的注释
Annotation[] annotations = method.getAnnotations();
try {
//noinspection unchecked
// 调用 retrofit.callAdapter() 得到目标 CallAdapter
return (CallAdapter<ResponseT, ReturnT>) retrofit.callAdapter(returnType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(method, e, "Unable to create call adapter for %s", returnType);
}
}
而 Retrofit#callAdapter()
最终会调用 Retrofit#nextCallAdapter()
,其中传递的参数 skipPast
为 null
。
public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
...
// 因为 skipPast == null,所以实际上会遍历整个 callAdapterFactories
int start = callAdapterFactories.indexOf(skipPast) + 1;
// 遍历 callAdapterFactories,然后调用每个 CallAdapter.Factory 元素的 get() 方法,
// 看是否能够得到第一个正常的将 Call 转换为 returnType 类型的 CallAdapter
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 完 callAdapterFactories 没有得到非空的 adapter,则会抛出异常
...
}
CallAdapter.Factory#get()
方法,会根据传入的 returnType
、annotations
,如果符合条件,就会返回对应的 CallAdapter
,否则,就会返回 null
。
例如,RxJavaCallAdapterFactory#get()
就会返回 RxJavaCallAdapter
,其可以将 Call
转换为 Observable
。
(2) 对于注释 2 的 createResponseConverter()
方法,其实现与 createCallAdapter()
类似,最终也会调用 Retrofit#nextResponseBodyConverter()
:
public <T> Converter<ResponseBody, T> nextResponseBodyConverter(
@Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
...
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;
}
}
// 如果遍历完 converterFactories 完也没有得到非空的 converter,那么也会报异常
...
}
responseBodyConverter()
会根据目标类型,来看是否能得到对应的 Converter
。
在第一部分的第 3 小点说过,当利用 Retrofit#create()
而生成的代理对象来调用在 XXXService
接口中定义的方法(如前面提到的 TestService
中的 testMothod()
)时:
@GET()
fun testMethod(@Path("path1") path: String): Call<ResponseBody>
// HttpServiceMethod # invoke()
@Override ReturnT invoke(Object[] args) {
return callAdapter.adapt(
new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
}
实例上会调用该方法对应的 HttpServiceMethod
实例的 invoke(OkHttpCall)
方法,然后间接调用 HttpServiceMethod
实例中设置的 callAdapter.adapt()
来返回 testMothod()
方法定义的返回值类型的实例,这里即 Call
类型的 call 实例。
因为 testMethod()
方法返回值设置的是 Call
类型,为默认的类型,因此 callAdapter
实际上就是 Retrofit
设置的默认的 CallAdapter
实例(因为不需要人为添加其他的 CallAdapterFactory
)。
还记得在 Refrofit.Builder#build()
中,会添加与平台相关的默认的 CallAdapterFactories
:
// Make a defensive copy of the adapters and add the default Call adapter.
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
在 Android 中即 Android (extends Platform)
的 defaultCallAdapterFactories()
:
@Override List<? extends CallAdapter.Factory> defaultCallAdapterFactories(
@Nullable Executor callbackExecutor) {
if (callbackExecutor == null) throw new AssertionError();
ExecutorCallAdapterFactory executorFactory = new ExecutorCallAdapterFactory(callbackExecutor);
return Build.VERSION.SDK_INT >= 24
? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
: singletonList(executorFactory);
}
当 SDK >= 24 时,默认有 CompletableFutureCallAdapterFactory
和 ExecutorCallAdapterFactory
;
否则,就只有 ExecutorCallAdapterFactory
。
其中 CompletableFutureCallAdapterFactory
会得到 BodyCallAdapter
或者 ResponseCallAdapter
类型的 callAdapter
。
// CompletableFutureCallAdapterFactory # get()
@Override public @Nullable CallAdapter<?, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != CompletableFuture.class) {
return null;
}
...
Type innerType = getParameterUpperBound(0, (ParameterizedType) returnType);
if (getRawType(innerType) != Response.class) {
// Generic type is not Response. Use it for body-only adapter.
return new BodyCallAdapter<>(innerType);
}
...
Type responseType = getParameterUpperBound(0, (ParameterizedType) innerType);
return new ResponseCallAdapter<>(responseType);
}
而 ExecutorCallAdapterFactory
会得到一个匿名的 CallAdapter
实例:
@Override public @Nullable 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);
}
};
}
针对接口方法设置的返回值为 retrofit2.Call 的情况。
// HttpServiceMethod # invoke()
@Override ReturnT invoke(Object[] args) {
// callAdapter.adapt() 会 new 一个 OkHttpCall 实例传递给 ExecutorCallbackCall 的构造函数
return callAdapter.adapt(new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
}
以 ExecutorCallAdapterFactory
举例,其对应的 HttpServiceMethod#invoke()
中的 callAdapter
就为 :
CallAdapter<Object, Call<?>>() {
@Override public Type responseType() {
return responseType;
}
@Override public Call<Object> adapt(Call<Object> call) {
// (1)传递的第一个参数,即为 ExecutorCallbackCall#callbackExecutor 成员变量赋值,
// 实际上是 Android(extends Platform) 中的 MainThreadExecutor。(第一部分有讲解)。
// (2)传递的第二个参数,即为 ExecutorCallbackCall#delegate 成员变量赋值,且根据前面
// 可知,实际为 OkHttpCall 类型的实例
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
类型,一个匿名类实例,通过该匿名类实例的 adapt()
方法,就返回 ExecutorCallbackCall
,以前面的实例代码为基础,假设有:
// interface TestService
@GET()
fun testMethod(@Path("path1") path: String): Call<ResponseBody>
// 示例代码
val testService = retrofit.create(TestService::class.java)
// 此时 call 的实际类型为 ExecutorCallbackCall
val call = testService.testMethod()
// 1
call.enqueue()
// 2
call.execute()
此时的 call
即为 ExecutorCallbackCall
。
// ExecutorCallAdapterFactory.ExecutorCallbackCall
static final class ExecutorCallbackCall<T> implements Call<T> {
final Executor callbackExecutor;
final Call<T> delegate;
ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
this.callbackExecutor = callbackExecutor;
// 形参 delegate 即在调用构造方法时传递过来的,根据前面的内容,可以知道实际上
// 为 OkHttpCall
this.delegate = delegate;
}
@Override public void enqueue(final Callback<T> callback) {
// 利用 delegate 实现异步请求
checkNotNull(callback, "callback == null");
delegate.enqueue(new Callback<T>() {
@Override public void onResponse(Call<T> call, final Response<T> response) {
// 请求成功的话,利用 callbackExecutor 来且回主线程
callbackExecutor.execute(new Runnable() {
@Override public void run() {
if (delegate.isCanceled()) {
// Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation.
// 调用回调接口的 onFailure() 方法
callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
} else {
// 调用回调接口的 onResponse() 方法
callback.onResponse(ExecutorCallbackCall.this, response);
}
}
});
}
@Override public void onFailure(Call<T> call, final Throwable t) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
// 调用回调接口的 onFailure() 方法
callback.onFailure(ExecutorCallbackCall.this, t);
}
});
}
});
}
@Override public Response<T> execute() throws IOException {
// 利用 delegate 实现同步请求
return delegate.execute();
}
...
}
当像示例代码那样调用 call.enqueue()
或者 call.execute()
时,则实际上是通过 delegate
来实现的,即通过 OkHttpCall
的 enqueue()\execute()
来实现的。
final class OkHttpCall<T> implements Call<T> {
private final RequestFactory requestFactory;
private final Object[] args;
private final okhttp3.Call.Factory callFactory;
private final Converter<ResponseBody, T> responseConverter;
private volatile boolean canceled;
@GuardedBy("this")
private @Nullable okhttp3.Call rawCall;
@GuardedBy("this") // Either a RuntimeException, non-fatal Error, or IOException.
private @Nullable Throwable creationFailure;
@GuardedBy("this")
private boolean executed;
OkHttpCall(RequestFactory requestFactory, Object[] args,
okhttp3.Call.Factory callFactory, Converter<ResponseBody, T> responseConverter) {
this.requestFactory = requestFactory;
this.args = args;
this.callFactory = callFactory;
this.responseConverter = responseConverter;
}
// 异步请求方法
@Override public void enqueue(final Callback<T> callback) {
checkNotNull(callback, "callback == null");
okhttp3.Call call;
Throwable failure;
synchronized (this) {
// 如果 call 已经执行过,则抛出异常
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
call = rawCall;
failure = creationFailure;
if (call == null && failure == null) {
try {
// 得到真正的原始的 okhttp3.Call
call = rawCall = createRawCall();
} catch (Throwable t) {
throwIfFatal(t);
failure = creationFailure = t;
}
}
}
if (failure != null) {
callback.onFailure(this, failure);
return;
}
if (canceled) {
call.cancel();
}
// 间接调用 call 的异步请求方法,且利用 okhttp3.Callback 间接实现回调
call.enqueue(new okhttp3.Callback() {
@Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
Response<T> response;
try {
// 将原始的 rawResponse 解析为 retrofit2.Response
response = parseResponse(rawResponse);
} catch (Throwable e) {
throwIfFatal(e);
callFailure(e);
return;
}
try {
// 回调在 ExecutorCallbackCall#enqueue() 中通过 delegate.enqueue()
// 传递的 retrofit2.Call#onResponse()
callback.onResponse(OkHttpCall.this, response);
} catch (Throwable t) {
t.printStackTrace();
}
}
@Override public void onFailure(okhttp3.Call call, IOException e) {
callFailure(e);
}
private void callFailure(Throwable e) {
try {
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable t) {
t.printStackTrace();
}
}
});
}
// 通过 requestFactory,根据给接口方法传入的参数,创建原始的 okhttp3.Call
private okhttp3.Call createRawCall() throws IOException {
// 这里就用到了在 ServiceMethod.parseAnnotations() 中生成的 requestFactory
// 而 callFactory 默认情况下则是 Retrofit.Budiler#build() 中设置的 OkHttpClient
okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
// 将关于 okhttp 最原始的 ResponseBody 转换为目标类型
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);
}
ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody);
try {
// 利用 responseConverter 将最原始的 catchingBody 转换为目标类型
// (1) 如果接口的方法定义的返回类型为 X,
// 则会将 catchingBody 转换为 okhttp3.ResponseBody
// (2) 如果是利用 GsonConverterFactory 将解烦的方法返回类型定义 X
// (ObjBean 为实体类),则 GsonResponseBodyConverter 会把 catchingBody
// 转换为对应的实体类 ObjBean 对象
T body = responseConverter.convert(catchingBody);
// 然后将转换后的 body 填充到 retrofit2.Response 中,
// 因为 parseResponse() 方法最终是返回 Response 类型的值
// 其中 T 即 body 对应的类型,也就是接口的方法定义的返回类型 X 中的类型 T
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;
}
}
}
通过 OkHttpCall
以及多重回调,最终实现了异步 Retrofit 的异步请求。
需要再次强调的是,此时请求的实现,是基于 CallAdapter 为 ExecutorCallAdapter 的情况。
另外,在上面的 parseResponse()
方法中有提到 "将 catchingBody
转换为 okhttp3.ResponseBody
" 。
此时是基于接口方法中定义的返回值为 X
来说的。
从 Retrofit.Builder#build()
中可知:
// Retrofit.Builder#build() 方法部分代码
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
converterFactories.addAll(platform.defaultConverterFactories());
会添加三类 ConverterFactory:
第一类是默认的 BuiltInConverters
;
第二类是在外部添加的;
第三类是与平台相关的默认的(对于 Android
来说,只有当 SDK >= 24 时,才会有一个 OptionalConverterFactory
,否则为空)。
因此可以推断出,当 基于接口方法中定义的返回值为 X
来说,对应的 Converter
为 BuiltInConverters.responseBodyConverter()
。
@Override public @Nullable Converter<ResponseBody, ?> responseBodyConverter(
Type type, Annotation[] annotations, Retrofit retrofit) {
// 如果目标类型为 okhttp3.ResponseBody,则返回对应的 Converte
if (type == ResponseBody.class) {
// 如果方法被标注了 @Streaming,则返回 StreamingResponseBodyConverter;
// 否则返回 BufferingResponseBodyConverter
return Utils.isAnnotationPresent(annotations, Streaming.class)
? StreamingResponseBodyConverter.INSTANCE
: BufferingResponseBodyConverter.INSTANCE;
}
if (type == Void.class) {
return VoidResponseBodyConverter.INSTANCE;
}
if (checkForKotlinUnit) {
try {
if (type == Unit.class) {
return UnitResponseBodyConverter.INSTANCE;
}
} catch (NoClassDefFoundError ignored) {
checkForKotlinUnit = false;
}
}
return null;
}
因此,从源码也印证了上面的推断,当设置的接口方法中的返回类型为 X
的时候,会使用 StreamingResponseBodyConverter/BufferingResponseBodyConverter
。
因为一般情况下,接口的方法不会使用 @Streaming
,因此这里以 BufferingResponseBodyConverter
进行讲解。
// BuiltInConverters # BufferingResponseBodyConverter
static final class BufferingResponseBodyConverter
implements Converter<ResponseBody, ResponseBody> {
static final BufferingResponseBodyConverter INSTANCE = new BufferingResponseBodyConverter();
@Override public ResponseBody convert(ResponseBody value) throws IOException {
try {
// Buffer the entire body to avoid future I/O.
return Utils.buffer(value);
} finally {
value.close();
}
}
}
// Utils.buffer()
static ResponseBody buffer(final ResponseBody body) throws IOException {
Buffer buffer = new Buffer();
body.source().readAll(buffer);
return ResponseBody.create(body.contentType(), body.contentLength(), buffer);
}
// ResponseBody.create()
public static ResponseBody create(final @Nullable MediaType contentType,
final long contentLength, final BufferedSource content) {
if (content == null) throw new NullPointerException("source == null");
return new ResponseBody() {
@Override public @Nullable MediaType contentType() {
return contentType;
}
@Override public long contentLength() {
return contentLength;
}
@Override public BufferedSource source() {
return content;
}
};
}
通过 BufferingResponseBodyConverter#convert()
,可以知道,其最终会根据传入的 value
(OkHttpCall#parseResponse()
里面说过,为 ExceptionCatchingResponseBody
实例),生成一个新的 ResponseBody
实例并返回。
其中,对于 OkHttpCall
来说,最原始的关于 okhttp 的 ResponseBody
其实是包装后的 ExceptionCatchingResponseBody
。
到这里,有关 Retrofit2.0 源码的梳理就基本结束了,当然这是在不涉及到额外设置的 CallAdapterFactory
、ConverterFactory
,一切都是走默认设置的情况下来说明的。
Retrofit 的底层是怎么实现网络请求的?
通过整篇文章的分析,就可以只是,是基于 OkHttp 来实现的。其实整个框架就是对 OkHttp 的再次封装。
CallAdapter 的作用,是怎么把 OkHttpCall
转换为 X
的,以及转换的时机?
(1) CallAdapter 的作用,就是得到接口中定义的方法的返回值类型对应的实例。
比如方法的返回值对应的为 retrofit2.Call
,则就有对应的 CallAdapter
将 HttpServiceMethod#invoke()
中传入给 callAdapter.adapt(OkHttpCall)
方法的 OkHttpCall
实例给转换为 retrofit2.Call
(实际上是 ExecutorCallbackCall
,其实现了 retrofit2.Call
),与其说是实现,其实说是包装更为准确,因为实际上还是要借助 OkHttpCall
来实现正在的网络请求。
又如 RxJavaCallAdapter
,则会将在 HttpServiceMethod#invoke()
中传入给 callAdapter.adapt(OkHttpCall)
方法的 OkHttpCall
实例包装成 rx.Observable
。
其实我一开始在没有了解清楚的时候,以为 RxJavaCallAdapter
是会将原始的retrofit2.Call
转换为 rx.Observable
,在反复阅读之后,才了解到 OkHttpCall
才是最原始的 Call
类型,通常情况下的 retrofit2.Call
中的 Call
对应的其实是 ExecutorCallbackCall
,即通常情况下的 retrofit2.Call
中的 Call
也是经过默认的 CallAdapter 转换来的。因此,如果前面中还有说 “ 将原始的retrofit2.Call
则是笔误,因为我是写到这里才领悟到的,见谅。
(2) 至于具体的转换,就得看具体的 CallAdapter
的 adapt()
方法的源码了。以 RxJavaCallAdapter#adapt()
为例,最终会将传入的 call
(即 OkHttpCall
实例)包装到 Observable
中。
(3) 至于转换的时机,则是在调用 HttpServiceMethod#invoke()
时,即调用 XXXService
对应的代理对象中定义的方法的时候。
Converter 的作用,以及是怎么把 ResponseBody
转换为 R
的?
具体的说,Converter 实际上分为好多类型:
(1) 用于将原始的 HTTP response body(即 OkHttpCall#parseResponse()
中的 catchingBody
)转换为接口方法的返回类型 X
中的 R 类型的 Converter,名义上被命名为 ResponseBodyConverter。
如 GsonConverterFactory
中的 GsonResponseBodyConverter
,会将封装了原始的 okhttp3.ResponseBody
的 catchingBody
转换为具体的实体类。
或者是默认的 Converter 将原始的关于 okhttp 的 catchingBody
直接转换为 ResponseBody
。
前面的内容也可能存在笔误,因为在定义的接口的方法返回值中定义的 ResponseBody
也是经过转换来的,并不是最原始的。
至于时机,则是在 OkHttpCall#parseResponse()
方法中调用 responseConverter.convert()
方法时。
(2) 名义上被称为 RequestBodyConverter 的 Converter,用于将接口方法中的参数转换为 RequestBody,且是被 @Body、@Part、@PartMap 注解修饰的参数。
比如 GsonConverterFactory
中的 GsonRequestBodyConverter
,可以将被 @Body 修饰的实体类类型的参数转换为 Json 格式的 RequestBody。
(3) 名义上被称为 StringConverter 的 Converter,用于将被 @Field、@FieldMap、@Header、@HeaderMap、@Path、@Query、@QueryMap 这几个注解修饰的参数转换为 String。
// Converter.Factory
abstract class Factory {
/**
* Returns a {@link Converter} for converting an HTTP response body to {@code type}, or null if
* {@code type} cannot be handled by this factory. This is used to create converters for
* response types such as {@code SimpleResponse} from a {@code Call}
* declaration.
*/
public @Nullable Converter<ResponseBody, ?> responseBodyConverter(Type type,
Annotation[] annotations, Retrofit retrofit) {
return null;
}
/**
* Returns a {@link Converter} for converting {@code type} to an HTTP request body, or null if
* {@code type} cannot be handled by this factory. This is used to create converters for types
* specified by {@link Body @Body}, {@link Part @Part}, and {@link PartMap @PartMap}
* values.
*/
public @Nullable Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
return null;
}
/**
* Returns a {@link Converter} for converting {@code type} to a {@link String}, or null if
* {@code type} cannot be handled by this factory. This is used to create converters for types
* specified by {@link Field @Field}, {@link FieldMap @FieldMap} values,
* {@link Header @Header}, {@link HeaderMap @HeaderMap}, {@link Path @Path},
* {@ink Query @Query}, and {@link QueryMap @QueryMap} values.
*/
public @Nullable Converter<?, String> stringConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
return null;
}
...
}
对于多个 CallAdapter,在接口中定义的多个方法,能不能定义不同的返回类型?
答案是能,可以实际尝试,比如,我可以同时为多个方法定义不同的返回值类型,如Observable
,Call
,Call
,都是能够正常运行的。(TranslationBean
为定义的一个实体类)
原因在上文中的源码解析也可体现,因为针对不同的返回值类型,会在 callAdapterFactories
针对其获取对应的 CallAdapter
。
对于多种 Converter,能不能把关于 okhttp 原始的 ResponseBody
转换为多种类型?
答案是能,由 4 可见,就同时存在 ResponseBody
与 TranslationBean
类型。同理,也会针对不用的目标类型在 converterFactories
找到对应的 Converter
。
在 Retrofit 中,是怎么生成一个 request 的?
是通过 requestFactory
生成的。进一步来说是在解析了注解方法的注解之后,得到对应的 requestFactory
实例,然后在 OkHttpCall#createRawCall()
方法中,调用 requestFactory.create()
并出传入方法的参数来生成的对应的 request。