参考资料:
retrofit注解大全:https://www.jianshu.com/p/e877b2f02966
https://blog.csdn.net/wan_dou_/article/details/116067728 (源码分析)
一、创建Retrofit实例
通过构造者设计模式构建retrofit实例
二、创建Service(接口)实例
public <T> T create(final Class<T> service) {
//检测service定义的方法的合法性
//将service中的方法反射缓存起来
validateServiceInterface(service);
//返回动态代理实例
return (T)
Proxy.newProxyInstance(
service.getClassLoader(),
new Class<?>[] {service},
new InvocationHandler() {
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;
Platform platform = Platform.get();
return platform.isDefaultMethod(method)
? platform.invokeDefaultMethod(method, service, proxy, args)
: loadServiceMethod(method).invoke(args);
}
});
}
- validateServiceInterface
-> loadServiceMethod
存储Map<Method, ServiceMethod<?>>
,将反射的结果保存起来,避免重复反射,影响性能。
ServiceMethod
-> parseAnnotations
|---- RequestFactory
-> Builder构造
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
//反射方法的注解
this.methodAnnotations = method.getAnnotations();
//反射方法的参数
this.parameterTypes = method.getGenericParameterTypes();
//反射方法参数的注解
this.parameterAnnotationsArray = method.getParameterAnnotations();
}
-> parseMethodAnnotation
解析HTTP请求方法上的各种注解:请求方法注解@GET等、请求头注解@Headers、标记注解@Multipart、@FormUrlEncoded
1)一个方法只能有一种HTTP注解
2)动态查询参数必需使用@Query注解
3)FormUrlEncoded与Multipart注解互斥,且只能用于带请求体的请求方法
4) 方法的返回类型不能是void
-> parseParameter
解析方法参数
->->parseParameterAnnotation
解析方法注解
各种方法参数的注解的报错日志就是这里打印的
->-> parseHttpMethodAndPath
请求方法及请求url解析
->-> parseHeaders
contentType解析
|---- HttpServiceMethod
-> parseAnnotations
createCallAdapter,创建CallAdapter对象
createResponseConverter,创建Converter对象
创建并返回HttpServiceMethod
- Proxy.newProxyInstance
返回动态代理创建的接口实例
Platform platform = Platform.get();
//获取Platform,判断方法是否是接口的默认方法。
return platform.isDefaultMethod(method)
? platform.invokeDefaultMethod(method, service, proxy, args)
: loadServiceMethod(method).invoke(args);
三、发起请求
所有的接口发起请求,最终都是通过动态代理走loadServiceMethod(method).invoke(args)
的方法,也就是HttpServiceMethod的invoke方法。
那么,看懂这块的代码,你需要懂kotlin协程。
参考一下博文https://www.jianshu.com/p/c9f123c21d82/
CallAdapter<ResponseT, ReturnT> callAdapter =
createCallAdapter();
Converter<ResponseBody, ResponseT> responseConverter =
createResponseConverter();
//不是挂起方法
if (!isKotlinSuspendFunction) {
return new CallAdapted<>();
} else if (continuationWantsResponse) {
//noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
return (HttpServiceMethod<ResponseT, ReturnT>)
new SuspendForResponse<>();
} else {
//noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
return (HttpServiceMethod<ResponseT, ReturnT>)
new SuspendForBody<>();
}
//TODO 未完待续...
0 条评论