这次主要分析动态代理实现的 invoke 方法,
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 (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);
}
}
invoke 方法里,主要做了三件事。第一件是判断该方法是不是 Object 的方法,例如 toString, clone 啊等等吧,如果是就以 Object 方法的调用方式执行。第二件是判断该方法是不是 Android 系统方法,这里有个 platform 变量,根据赋值来源就会发现它是用来区分 Java 还是 Android 平台。这点在官网上也有提到,Retrofit 支持 Android 和 Java 平台,显然如果运行在安卓系统上,那就应该是 Android 平台。第三件是调用 loadServiceMethod 方法,这个才是我们需要关心的。
ServiceMethod<?> loadServiceMethod(Method method) {
ServiceMethod<?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = ServiceMethod.parseAnnotations(this, method);
serviceMethodCache.put(method, result);
}
}
return result;
}
方法的大致逻辑是从 serviceMethodCache 缓存里找到 method 对应的 ServiceMethod 类型对象,如果找不到需要做一次加载,并将对象存入缓存中。这里的加载过程值得我们去关注一下,代码比较多,先分析下大致步骤,
- 调用 ServiceMethod 的静态方法 parseAnnotations,大意是利用 Retrofit 对象以及 Method 对象进行解析。
- 首先做的就是通过解析创建出一个 RequestFactory 对象,这个对象里包含着很多信息,例如请求方式(即 POST 还是 GET 等请求),请求头,contentType 等等。
- 接着通过 HttpServiceMethod 的静态方法 parseAnnotations 进一步解析,入参有 Retrofit 对象,Method 对象和刚才创建的 RequestFactory 对象。
- HttpServiceMethod 继承自 ServiceMethod,但也是个抽象类,这个类提供的 parseAnnotations 方法的主要内容是进一步解析,并创建前面说过的适配器和转换器,最后利用 RequestFactory 对象,OkHttp 对象,转换器对象,适配器对象创建了一个 CallAdapted 类型的对象并返回。
- CallAdapted 类是 HttpServiceMethod 的子类,实现了父类的抽象方法 adapt。而 HttpServiceMethod 又实现了 ServiceMethod 的抽象方法 invoke,在 invoke 方法里调用了 adapt 方法。
- 所以前面说到的加载过程,最终就是返回了一个 CallAdapted 类型的对象,并存到缓存中。接下去就是调用了 CallAdapted 对象的 invoke 方法,显然最终调用了 CallAdapted 自身的 adapt 方法。
- CallAdapted 提供的 adapt 方法里就一句,那就是调用适配器的 adapt 方法,并返回一个值。
- 前面说过,以 RxJava2CallAdapter 适配器为了,最终就是调用了它的 adapt 方法,入参是 Call 类型对象,这个 Call 就是请求的关键。
综上,调用网络请求的方法之后就会触发以上的一系列操作,后面将会从两个角度继续分析,一个是看看这个 Call 的生成及后续,一个是看看涉及到的 RxJava2 相关的东西。
网友评论