(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.adapt(okHttpCall);
}
});
}
这里我们看到了 validateEagerly 变量,让我们看看它到底控制了什么。进 eagerlyValidateMethods 方法。
private void eagerlyValidateMethods(Class<?> service) {
Platform platform = Platform.get();
for (Method method : service.getDeclaredMethods()) {
if (!platform.isDefaultMethod(method)) {
loadServiceMethod(method);
}
}
}
ServiceMethod<?, ?> loadServiceMethod(Method method) {
ServiceMethod<?, ?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = new ServiceMethod.Builder<>(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
这里又见到了 Platform ,在 Retrofit.Builder 我们知道它返回的是 Android() 对象。 接着是个 循环 ,循环取出接口中的 Method ,接着调用 loadServiceMethod 。 loadServiceMethod 里面会根据 Method 生成一个 ServiceMethod,然后存入 serviceMethodCache , 那么我们大概知道,这是属于提前验证,会提前把接口中每个方法进行解析得到一个 ServiceMethod 对象,然后存入缓存中。 在 loadServiceMethod 中会取缓存中的值,如果有就直接返回 ServiceMethod。
由此可以知道 validateEagerly 变量是用于 判断是否需要提前验证解析的。
create 方法中 继续往下走,会看到 return 一个 代理对象 Proxy ,并转成了 T 类型,即 GitHubService 。
此时我们这句代码 GitHubService service = retrofit.create(GitHubService.class);
中的 service 有值了,它指向一个 实现了 GitHubService 接口的 代理对象 Proxy 。
3. 拿到 Call 对象 , 即 Call<List<Repo>> repos = service.listRepos("octocat");
这里我们的 service 是个代理对象,所以执行 listRepos 方法时, 会先走 InvocationHandler 中的 invoke 方法。
public T create(final Class service) {
Utils.validateServiceInterface(service);
if (validateEagerly) {
eagerlyValidateMethods(service);
}
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();
@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.
// 如果这个方法是声明在 Object 类中,那么不拦截,直接执行
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
// 这个总是返回的false,所以不用关心
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
// 下面三行代码非常重要,重点分析,分别对应 3.1 3.2 3.3 三个小节
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.adapt(okHttpCall);
}
});
}
3.1 ServiceMethod<Object, Object> serviceMethod = (ServiceMethod<Object, Object>) loadServiceMethod(method);
首先 ServiceMethod 我们之前猜测过,应该是对 Method 的一个封装, 而这个 loadServiceMethod ,如果你还记得的话,我们在 create 的时候就碰到过,eagerlyValidateMethods 这个方法内部调用过 loadServiceMethod ,是为了加载这个 ServiceMethod 。现在我们来深入分析这个 loadServiceMethod 方法。
ServiceMethod<?, ?> loadServiceMethod(Method method) {
// 首先从 缓存 serviceMethodCache 中取 ServiceMethod ,如果存在就返回,不存在继续往下走。
// 也就是说 我们的 ServiceMethod 只会创建一次。
ServiceMethod<?, ?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
//这里又从缓存取了一遍,看到这里有没有一种熟悉的感觉,是不是跟 DCL 单例模式特别像,双重校验。
result = serviceMethodCache.get(method);
if (result == null) {
result = new ServiceMethod.Builder<>(this, method).build();
serviceMethodCache.put(method, result);
}
}