玩 Android 比较晚,现在才开始看 Retrofit,但是一直搞不明白,为什么写个接口(方法都是抽象方法)传进去,框架就可以知道我要传的参数以及返回值呢?
稍稍进入源码然后看到原来是用的动态代理,原理就是:一个接口被动态代理,只要调用代理类的任何的方法,都可以获得该方法的参数以及方法注解,然后既可以做任何事情了(要的就是接口中的方法的参数以及方法注解)!
Retrofit 的 create 方法,使用了动态代理(只保留了动态代理相关的内容):
public create(finalClassservice) {
return (T) Proxy.newProxyInstance(service.getClassLoader() , newClass[] {service} ,
new InvocationHandler() {
@Override
public Object invoke (Object proxy,Method method,Object[] args)
throws Throwable{
});
}
下面写一个 Java 的 Demo 来解释这一个过程:
首先新建一个接口:
public interface Subject {
@Deprecated //可以类比方法上的接口
String getName(String a,String b); //两个参数
String fromatName(String a , String b);
}
写测试类:
public class Test {
public static void main(String[] args) {
//获取InvocationHandler
InvocationHandler handle = new InvokeHandle();
//获取动态代理类
Subject s = getProxy(handle.getClass().getClassLoader(), new Class[] { Subject.class }, handle);
//调用动态代理的方法
System.out.println(s.getName("android", "developer"));
System.out.println(s.fromatName("java", "so easy"));
}
//方法 获取代理对象
public static Subject getProxy(ClassLoader classLoader, Class[] c, InvocationHandler handler) {
return (Subject) Proxy.newProxyInstance(classLoader, c, handler);
}
//内部类实现了InvocationHandler
public static class InvokeHandle implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//获取当前调用方法上的注解
Annotation[] anno = method.getAnnotations();
for (Annotation annotation : anno) {
System.out.println(annotation.toString());
}
//获取当前调用方法上的所有参数
for (Object object : args) {
System.out.print(object + " ");
}
//到这里已经拿到了方法上所有的注解以及参数,然后就可以想干啥干啥了 。。。
System.out.println();
return "成功获取参数";
}
}
}
嗯嗯,好吧,就是这么简单。