美文网首页
为什么 Retrofit 将接口传进去就可以进行网络请求(用 J

为什么 Retrofit 将接口传进去就可以进行网络请求(用 J

作者: learnice | 来源:发表于2017-07-15 23:35 被阅读0次

玩 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 "成功获取参数";

    }

}

}

嗯嗯,好吧,就是这么简单。

相关文章

网友评论

      本文标题:为什么 Retrofit 将接口传进去就可以进行网络请求(用 J

      本文链接:https://www.haomeiwen.com/subject/ziozhxtx.html