retrofit简单使用以及源码分析

retrofit相关文章虽然对,作为学习笔记使用,有问题希望能够尽情提出,共同交流
蒋八九

概述

retrofit说白了就是动态代理的原理,这篇文章源码分析不对,要是了解动态的代理的话,那么retrofit就没什么难度的了

注解的基本知识

  1. @Retention – 定义该注解的生命周期
    ● RetentionPolicy.SOURCE : 在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。@Override, @SuppressWarnings都属于这类注解。
    ● RetentionPolicy.CLASS : 在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式
    ● RetentionPolicy.RUNTIME : 始终不会丢弃,运行期也保留该注解,因此可以使用反射机制读取该注解的信息。我们自定义的注解通常使用这种方式。
  2. Target – 表示该注解用于什么地方。默认值为任何元素,表示该注解用于什么地方。可用的ElementType 参数包括
    ● ElementType.CONSTRUCTOR: 用于描述构造器
    ● ElementType.FIELD: 成员变量、对象、属性(包括enum实例)
    ● ElementType.LOCAL_VARIABLE: 用于描述局部变量
    ● ElementType.METHOD: 用于描述方法
    ● ElementType.PACKAGE: 用于描述包
    ● ElementType.PARAMETER: 用于描述参数
    ● ElementType.TYPE: 用于描述类、接口(包括注解类型) 或enum声明
    ● ElementType.ANNOTATION_TYPE
  3. @Documented – 一个简单的Annotations 标记注解,表示是否将注解信息添加在java 文档中。
  4. @Inherited – 定义该注释和子类的关系
    @Inherited 元注解是一个标记注解,@Inherited 阐述了某个被标注的类型是被继承的。如果一个使用了 @Inherited 修饰的annotation 类型被用于一个class,则这个annotation 将被用于该class 的子类。

设计模式:

建造模式、动态代理模式

主要实现方法:

一、首先通过build构造器构造一个Retrofit对象,也就将url地址、converterFactory(gson解析器)、rxjava适配工厂、okhttpClient对象,都封装到Retrofit中去。

Retrofit mRetrofit = new Retrofit.Builder().baseUrl(params.url)
        .addConverterFactory(factory)
        .addCallAdapterFactory(adapterFactory)
        .client(mOkHttpClient)
        .callFactory(params.callFactory).build();

二、然后调用mRetrofit.create()方法,通过动态代理的方式,得到请求接口的代理类。当调用这个类中的请求方法时就会触发这个代理类的invok方法进行网络请求,并最终返回请求结果。

1、通过create方法传入class字节码,通过反射机制获取自定义接口类实例;
RetrofitApi retrofitApi = retrofit.create(RetrofitApi.class);
public <T> T create(final Class<T> service) {
2、限定自定义类必须是一个无继承的接口类,不然抛异常
  Utils.validateServiceInterface(service);
  ..........
3、使用jdk的动态代理机制,实现InvocationHandler的匿名内部类
  return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
      new InvocationHandler() {   //实现InvocationHandler匿名内部类
..........
4、当调用retrofitApi中的方法的时候,通过动态代理机制间接的触发invoke方法。
        @Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
            throws Throwable {
5、这里Object的方法指的是toString、equals、hashcode等方法
          if (method.getDeclaringClass() == Object.class) {
            return method.invoke(this, args);
          }
          if (platform.isDefaultMethod(method)) {
            return platform.invokeDefaultMethod(method, service, proxy, args);
          }
6、将Method方法中的注解、类型等信息解析成ServiceMethod对象,然后存放到ServiceMethodCache缓存HashMap中,这是Retrofit类中的ConcurrentHashmap集合,以Method为key,ServiceMethod为值存放。
          ServiceMethod<Object, Object> serviceMethod =
              (ServiceMethod<Object, Object>) loadServiceMethod(method);
7、将缓存请求方法的ServiceMethod对象和请求入参args一起包装到OkHttpCall对象中。
          OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
8、最后根据一系列的判断,将okHttpCall装饰成最终的特定的Observable类型,然后返回。所以这里的adapt其实就相当于一个适配器模式。
          return serviceMethod.adapt(okHttpCall);
        }
      });
}

猜你喜欢

转载自blog.csdn.net/massonJ/article/details/107958032