version:2.9
- retrofit.create利用动态代理 Proxy.newProxyInstance
- ServiceMethod<?> loadServiceMethod(Method method) {}
- static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {}
public <T> T create(final Class<T> service) {
Utils.validateServiceInterface(service);
if (validateEagerly) {
eagerlyValidateMethods(service);
}
// 上面都分析过了,这里直接通过动态代理的方式返回了一个 T 的代理对象,这个T就是传递过来的泛型,
// 这个例子中也就是 MovieService。
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 {
// 如果传递进来的是 Object类型,那么按照常规执行,事实上正常使用不会传递 Object
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
// 这个 isDefaultMethod 是一直返回的 false 的,所以这里也不会执行
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
// 关键代码就是这三行了,以此分析
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
然后就是下面这个代码,我们发现这个实际作用就是切回到主线程,所以套一层ExecutorCallbackCall的作用就是把网络请求的后台线程切回到主线程。
static final class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override
public void execute(Runnable r) {
handler.post(r);
}
}
总结:
通过上面的分析我们可以看到 Retrofit 是在内部通过大量的设计模式对 OkHttp 库的又一层封装,让我们使用者更加方便的进行网络请求。
其内部的核心就是通过动态代理,将定义的网络请求接口生成对应的代理对象,然后在执行代理对象方法调用的时候,会通过反射把调用的方法信息封装在 ServiceMethod 中,拿到 OkHttpCall 的包装类,最后通过包装类里面调用 OkhttpCall 调用 OkHttp 的方式完成网络请求。