我们都知道Retrofit 中写网络请求,都是直接写一个接口,在接口里写对应的方法,返回类型是Call,如下:
public interface ITransactionService {
@GET(NetManager.TRANSACTION_LIST) Call<List<TransactionRec>> getTransactionRecords(@QueryMap(encoded=true) );
}
Retrofit retrofit=new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(StringConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.client(OkhttpFactory.singletonOkHttp(context,mNotInterceptLog))
.build();
Call<List<TransactionRec>> call= retrofit.create(ITransactionService.class);call.enqueue(new Callback<M>() {
@Override public void onResponse(Call<M> call, retrofit2.Response<M> response) {
}
@Override public void onFailure(Call call, Throwable t) {
});
以上代码就是retrofit的大致写法,那么Call对象究竟是怎么生成的 ,一个没有实现类的接口是怎么支持里面的方法的呢?
通过分析源码发现,他的create 方法里是使用代理的方式实现,真正实现方法是InvocationHandler里的invoke方法,通过ServiceMethod类去解析getTransactionRecords方法上声明的注解和入参类型,获取的网络数据通过先前注册的相应的ConverterFactory来解析得到封装好的数据类型,源码如下;
public <T> T create(final Class<T> 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, 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); } ServiceMethod<Object, Object> serviceMethod = (ServiceMethod<Object, Object>) loadServiceMethod(method); OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args); return serviceMethod.callAdapter.adapt(okHttpCall); } }); }
这一巧妙的动态代理方式,减少了请求方法的编写及数据解析的过程,让开发者更多的关注业务逻辑。