val retrofit = Retrofit.Builder()
.baseUrl("https://api.device.cn/")
.callFactory(OkHttpClient())
.addConverterFactory(GsonConvertFactory.create())
//.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
//.addCallAdapterFactory(HiCallAdapterFactory.create())
.build();
interface Api {
//默认情况下方法返回类型为Call<T>,response类型为ResponseBody
@GET("/user/detail")
fun userDetail(): Call<ResponseBody>
}
Call<User> caller= retrofit.create(Api.class).userDetail();
caller.enqueue(new Callback(){...});
Retrofit执行原理简述
Retrofit执行原理是,通过执行内部方法create作为接口请求的起始。进入通过执行动态代理生成接口对象,调用接口对象方法并回调动态代理的invoke方法。在回调invoke方法过程中,会解析接口对象方法的注解、方法参数注解、方法返回值类型并将解析内容封装成对象。待执行到ServiceMethod.invoke()时,Call对象执行同步/异步请求,使得okhttp的拦截器BridgeIntercdeptor通过chain.proceed(requestBuilder.build())传入request对象(通过已解析的注解内容所生成),然后执行最终的接口数据请求,并返回响应报文。
Retrofit执行源码拆解
在执行Retrofit.Builder()…build();方法build时,生成Retrofit对象过程中,
若callFactory我们未指定则默认使用OkHttpClient。
若callbackExecutor未指定则默认使用Handler。
若CallAdapterFactory未指定则默认使用DefaultCallAdapterFactory(使得响应报文,返回类型默认是Call<ResponseeBody>
)
retrofit.create(Api.class)
在retrofit执行到方法create时,通过动态代理类获取到Api接口实例。在执行动态代理前会先判断该传入的Api.class是否是接口类型validateServiceInterface(service);
,否则抛出异常。
retrofit.create(Api.class).userDetail()
在retrofit执行到方法userDetail时,则是通过接口Api实例对象执行方法userDetail()。此时会回调动态代理的方法invoke()。在invoke方法中
1,如果方法是来自Object的方法,则直接调用method.invoke(this, args)
。
2,如果方法是默认方法,则platform.invokeDefaultMethod(method, service, proxy, args)
。
3,反之,执行loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
在执行到loadServiceMethod(method)
,进入ServiceMethod.java类中。即对Api接口的userDetail()方法注解、方法参数注解及返回值类型进行解析,并获得CallAdapter实例。解析的具体实现,体现在RequestFactory.parseAnnotations(retrofit, method);
方法中。解析完成后封装解析内容在类RequestFactory中。之后继续执行HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
目的是使用RequestFactory得到CallAdapter<ResponseT, ReturnT>
的实例对象callAdapter。
// ServiceMethod.java
abstract class ServiceMethod<T> {
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
// 注解解析
RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
... ...
// 获得CallAdapter对象实例
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
}
获得callAdappter实例后,获取实例源码如下
// HttpServiceMethod.java
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
......
// 获得callAdapter实例
CallAdapter<ResponseT, ReturnT> callAdapter =
createCallAdapter(retrofit, method, adapterType, annotations);
.... .....
// 创建HttpServiceMethod的实现类,并作为CallAdapter的代理类。替代CallAdapter。
if (!isKotlinSuspendFunction) {
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
}
}
接下来,在Retrofit.java的create方法中,会执行loadServiceMethod(method).invoke(args != null ? args : emptyArgs)
中的invoke(args != null ? args : emptyArgs)方法。使用多态方式,形式上是执行了ServiceMethod.invoke(args != null ? args : emptyArgs),实际是其实现类CallAdapted.invoke(args != null ? args : emptyArgs)在执行。之后顺着逻辑进入HttpServiceMethod#invoke方法中
@Override final @Nullable ReturnT invoke(Object[] args) {
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}
会发现,在invoke方法中通过OkHttpCall创建了Call的实例对象。创建Call实例目的是干啥?是为通过Call做网络请求的!之后会由HttpServiceMethod#invoke方法进入CallAdapted#invoke方法,执行callAdapter.adapt(call)。默认情况下,执行流程会进入DefaultCallAdapterFactory类中。执行类中匿名内部类的adapt方法。终,返回了一个Call代理类ExecutorCallbackCall(或者说是实现类)实例,为后面执行网络请求(如enqueue(final Callback callback))做铺垫。
// DefaultCallAdapterFactory.java
final class DefaultCallAdapterFactory extends CallAdapter.Factory {
... ........
@Override public @Nullable CallAdapter<?, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit) {
. .... ...
return new CallAdapter<Object, Call<?>>() {
@Override public Type responseType() {
return responseType;
}
// 默认情况下,执行流程会进入DefaultCallAdapterFactory的匿名内部类的adapt方法
@Override public Call<Object> adapt(Call<Object> call) {
return executor == null // 默认非空,是Handler
? call
: new ExecutorCallbackCall<>(executor, call);
}
};
}
caller.enqueue(new Callback(){…})
在retrofit执行到方法enqueue时,即是拿ExecutorCallbackCall实例,调用其enqueue方法,发起网络请求并获得响应报文。然后将响应报文的回调切换到UI线程。
// ExecutorCallbackCall.java 为 Call.java的代理类
static final class ExecutorCallbackCall<T> implements Call<T> {
... ...
ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
this.callbackExecutor = callbackExecutor;
this.delegate = delegate;
}
@Override public void enqueue(final Callback<T> callback) {
Objects.requireNonNull(callback, "callback == null");
delegate.enqueue(new Callback<T>() {// Call执行异步请求
@Override public void onResponse(Call<T> call, final Response<T> response) {
callbackExecutor.execute(() -> {// 通过Handler切换线程到UI线程
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);// 回调响应报文给用户
}
});
}
... ...
}