前言
今天是下雨的一天,在家呆着没事 so 看看代码吧
分析
– Retrofit对象是如何创建的
对于经常使用Retrofit网络框架的小伙伴来说这个简直太容易回答了 (通过建造者模式来创建),不过虽然如此我们还是仔细悄悄内部的逻辑
// 通过这个Builder的构造器获取一个Android平台的 Platform对象
public Builder() {
this(Platform.get());
}
// get方法返回的是一个Android对象
static Platform get() {
return PLATFORM;
}
private static Platform findPlatform() {
switch (System.getProperty("java.vm.name")) {
case "Dalvik":
return new Android();
case "RoboVM":
return new Platform(false);
default:
return new Platform(true);
}
}
// get方法返回的Android对象的类 内部包含一个使用hander进行线程切换的executor对象
static final class Android extends Platform {
Android() {
super(Build.VERSION.SDK_INT >= 24);
}
@Override
public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
@Nullable
@Override
Object invokeDefaultMethod(
Method method, Class<?> declaringClass, Object object, Object... args) throws Throwable {
if (Build.VERSION.SDK_INT < 26) {
throw new UnsupportedOperationException(
"Calling default methods on API 24 and 25 is not supported");
}
return super.invokeDefaultMethod(method, declaringClass, object, args);
}
static final class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override
public void execute(Runnable r) {
handler.post(r);
}
}
}
}
上边的代码就是通过Builder的构造器中获取一个Android平台的Platform对象,这个对象是一个内部包含一个可以进行线程切换的MainThreadExecutor(通过Handler来实现的)
Builder的构造方法说完了 ,我们再来看看build()方法
public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
// 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));
// 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.
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
converterFactories.addAll(platform.defaultConverterFactories());
return new Retrofit(
callFactory,
baseUrl,
unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories),
callbackExecutor,
validateEagerly);
}
}
这内部包含对callFactory的创建,没有callAdapterFactory时候默认的DefaultCallAdapterFactory的创建,已经添加的 callAdapterFactory,converterFactories的保存,接着调用Retrofit的构造器来创建对象,至此创建的工作算是完成了。
– Api接口的对象的创建
说到这大部分人也都知道 就是通过 Proxy.newProxyInstance()这个方法来实现的,当接口中定义的方法被调用的时候会触发invocationHandler()中的invoke方法,进而触发注解解析,生成request等的逻辑
public <T> T create(final Class<T> service) {
validateServiceInterface(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 @Nullable 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);
}
args = args != null ? args : emptyArgs;
return platform.isDefaultMethod(method)
? platform.invokeDefaultMethod(method, service, proxy, args)
: loadServiceMethod(method).invoke(args);
}
});
}
在Create方法中会执行 loadServiceMethod()-> ServiceMethod{parseAnnotations()}在parseAnnotations()方法内部通过
RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
获取一个RequestFactory 对象 它包括对注解的解析和使用解析到的参数来生成request对象,执行完刚刚的代码段接着会执行
HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
来创建一个HttpServiceMethod继承ServiceMethod的对象之后在他的invoke()方法中进行Call对象的初始化,进而借助okhttp发起网络请求
接下来对 HttpServiceMethod中的parseAnnotations()方法进行分析此处分为是普通的方法的处理和对suspend方法的处理 如果是普通方法
adapterType = method.getGenericReturnType();
获取Call对象中的范型类型
如果是suspend方法
Type responseType =
Utils.getParameterLowerBound(
0, (ParameterizedType) parameterTypes[parameterTypes.length - 1]);
if (getRawType(responseType) == Response.class && responseType instanceof ParameterizedType) {
// Unwrap the actual body type from Response<T>.
responseType = Utils.getParameterUpperBound(0, (ParameterizedType) responseType);
continuationWantsResponse = true;
} else {
// TODO figure out if type is nullable or not
// Metadata metadata = method.getDeclaringClass().getAnnotation(Metadata.class)
// Find the entry for method
// Determine if return type is nullable or not
}
adapterType = new Utils.ParameterizedTypeImpl(null, Call.class, responseType);
annotations = SkipCallbackExecutorImpl.ensurePresent(annotations);
通过参数列表的最后一个参数Continuation对象获取返回值的类型,在通过工具类包装成 adapterType
接下来通过就是创建CallAdapter 和对返回的类型进行转化的转化器
CallAdapter<ResponseT, ReturnT> callAdapter =
createCallAdapter(retrofit, method, adapterType, annotations);
Converter<ResponseBody, ResponseT> responseConverter =
createResponseConverter(retrofit, method, responseType);
进而创建一下CallFatory的适配对象 ,进入默认的CallAdapterFactory和配置的一些适配器的处理逻辑了 发起请求,数据回调等
static final class CallAdapted<ResponseT, ReturnT> extends HttpServiceMethod<ResponseT, ReturnT> {
private final CallAdapter<ResponseT, ReturnT> callAdapter;
CallAdapted(
RequestFactory requestFactory,
okhttp3.Call.Factory callFactory,
Converter<ResponseBody, ResponseT> responseConverter,
CallAdapter<ResponseT, ReturnT> callAdapter) {
super(requestFactory, callFactory, responseConverter);
this.callAdapter = callAdapter;
}
@Override
protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
return callAdapter.adapt(call);
}
}
static final class SuspendForResponse<ResponseT> extends HttpServiceMethod<ResponseT, Object> {
private final CallAdapter<ResponseT, Call<ResponseT>> callAdapter;
SuspendForResponse(
RequestFactory requestFactory,
okhttp3.Call.Factory callFactory,
Converter<ResponseBody, ResponseT> responseConverter,
CallAdapter<ResponseT, Call<ResponseT>> callAdapter) {
super(requestFactory, callFactory, responseConverter);
this.callAdapter = callAdapter;
}
@Override
protected Object adapt(Call<ResponseT> call, Object[] args) {
call = callAdapter.adapt(call);
//noinspection unchecked Checked by reflection inside RequestFactory.
Continuation<Response<ResponseT>> continuation =
(Continuation<Response<ResponseT>>) args[args.length - 1];
// See SuspendForBody for explanation about this try/catch.
try {
return KotlinExtensions.awaitResponse(call, continuation);
} catch (Exception e) {
return KotlinExtensions.suspendAndThrow(e, continuation);
}
}
}
static final class SuspendForBody<ResponseT> extends HttpServiceMethod<ResponseT, Object> {
private final CallAdapter<ResponseT, Call<ResponseT>> callAdapter;
private final boolean isNullable;
SuspendForBody(
RequestFactory requestFactory,
okhttp3.Call.Factory callFactory,
Converter<ResponseBody, ResponseT> responseConverter,
CallAdapter<ResponseT, Call<ResponseT>> callAdapter,
boolean isNullable) {
super(requestFactory, callFactory, responseConverter);
this.callAdapter = callAdapter;
this.isNullable = isNullable;
}
@Override
protected Object adapt(Call<ResponseT> call, Object[] args) {
call = callAdapter.adapt(call);
//noinspection unchecked Checked by reflection inside RequestFactory.
Continuation<ResponseT> continuation = (Continuation<ResponseT>) args[args.length - 1];
// Calls to OkHttp Call.enqueue() like those inside await and awaitNullable can sometimes
// invoke the supplied callback with an exception before the invoking stack frame can return.
// Coroutines will intercept the subsequent invocation of the Continuation and throw the
// exception synchronously. A Java Proxy cannot throw checked exceptions without them being
// declared on the interface method. To avoid the synchronous checked exception being wrapped
// in an UndeclaredThrowableException, it is intercepted and supplied to a helper which will
// force suspension to occur so that it can be instead delivered to the continuation to
// bypass this restriction.
try {
return isNullable
? KotlinExtensions.awaitNullable(call, continuation)
: KotlinExtensions.await(call, continuation);
} catch (Exception e) {
return KotlinExtensions.suspendAndThrow(e, continuation);
}
}
}