最近在没事,就想看看Retrofit的源码,梳理一下这么主流的网络框架是怎么执行的。直到我点进去后,发现里面大量使用了一些特别好的设计模式,所以,我想摘录下来,巩固一下这些知识点。
Android中的网络注解框架Retrofit内部实现其实就是应用了动态代理技术,通常我们定义的网络接口是这样的:
public interface ApiStore {
// 员工登录
@FormUrlEncoded
@POST("/resource/d/member/login")
Observable<BaseResponse<LoginResult>> login(@FieldMap Map<String, String> params);
// 退出登录
@FormUrlEncoded
@POST("/resource/d/member/signOut")
Observable<BaseResponse<LogOutResult>> logout(@FieldMap Map<String, String> params);
//....
}
创建Retrofit:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://ww.xxx.com/")
.build();
ApiStore service = retrofit.create(ApiStore.class);
当我们点进去create方法,这句代码其实就是创建了一个代理类Proxy
@SuppressWarnings("unchecked") // Single-interface proxy creation guarded by parameter safety.
public <T> T create(final Class<T> service) {
//检查传入的类为接口并且无继承
Utils.validateServiceInterface(service);
if (validateEagerly) {
//判断是否需要提前验证
//需要注意的,如果不是提前验证则进行动态解析对应方法
eagerlyValidateMethods(service);
}
//重点是这里
//首先返回一个利用代理实现的GitHub对象
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 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);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}
});
}
上面代码中retrofit就是通过Proxy.newProxrInstance()Service.getClassLoader(),new Class<?>[]{service},new invocationHandler())的方式创建的一个代理类。
invoke中的代码就是当网络接口被调用的时候需要做的处理。在这个方法里面,首先根据接口定义的方法,去生成一个ServiceMethod对象。在这个ServiceMethod对象中会反射接口中定义的注解,解析出具体的网络请求方式。
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); //以Method为键将该对象存入LinkedHashMap集合中
}
}
return result;
}
最后,loadServiceMethod(method).invoke(args != null ? args : emptyArgs)方法中的invoke方法中中,具体是实现了创建OkHttpCall对象。便于进行真正的网络请求(OKHttp)
@Override ReturnT invoke(Object[] args) {
return callAdapter.adapt(
new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
}
以上这里,我们就已经宏观的了解到Retrofit是怎样通过代理,解析接口注解,最后调用OKHttp去实现网络请求的一个流程。