Quantcast
Channel: CSDN博客移动开发推荐文章
Viewing all articles
Browse latest Browse all 5930

Retrofit 原理简析

$
0
0

简介

  Retrofit 所做的事情简单来说就是将你的 Http 业务 API --> Http 请求实现,类似于 Spring MVC 中的 Controller,它的主要任务是解析你的业务接口,从接口上获取你的 Http 接口协议,然后组装 Http 请求,进行异步 Request。
  Retrofit 整合了多个组件,包括 JSON/XML 的 ORM 映射,用于解析返回值;Http请求驱动用语发送 Http 请求,Retrofit 默认使用的是 Okhttp;异步处理框架,包括Observable。

原理

  如何生成一个接口的实现类,除了手动实现该接口之外,还有另外一种选择,那就是动态代理;Retrofit 的核心正是如此。
  如同 SpringMVC 的 Controller 一样,在方法描述上(方法描述包括 Modifiers,参数列表,返回值类型,异常列表),再加上参数列表上的注解,方法体上的注解,通过一个方法的描述就可以基本确定一个 Http 接口的所有协议了。

1. 请 求 目 标 地 址 和 请 求 方 法 :

  通 过 解 析 方 法 体 上 的 注 解 。 类 似 这 种@POST("/mobile/login") 代表请 POST 方法,地址“Domain/mobile/login”。

2.请求参数:

  通过解析参数列表和参数列表上的注解,如(@Query("loginname")StringloginName, @Query("pass")String pass) 代表其有两个参数 loginName,pass。

3. 请求返回值:

  通 过 解 析 方 法 的 返 回 值 类 型 。 例 如Observable<baseresponse> Observable 是异步可观测数据 RxJava 的包裹类,真正的业务 Model 类型在范型里面。

源码分析

  先来看创建 API 代理的入口方法 Retrofit.create(Class class):
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, @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);
            }
            ServiceMethod<Object, Object> serviceMethod =
                (ServiceMethod<Object, Object>) loadServiceMethod(method);
            OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
            return serviceMethod.callAdapter.adapt(okHttpCall);
          }
        });
  }

1.Utils.validateServiceInterface(service):

  检查传进来的 Class 对象是否合法,主要检查两个方面一是 Class 是否是接口,二是接口一定不能继承其他接口。

2.eagerlyValidateMethods(service):

  validateEagerly 这个参数控制了是否是在 create 是提前解析业务接口并且进行缓存,否则的话将需要在业务方法调用时解析。

3.Platform:

  如字面所描述平台类,Retrofit 专门为操作系统运行环境抽象了一层,事实上,Retrofit 可以运行在 Android,IOS,Java8 三个平台上。获取比较诡异的事为什么 Java代码可以在 IOS 平台运行,事实上是借助了一个叫 robovm 的第三方 JVM,Class.forName("org.robovm.apple.foundation.NSOperationQueue"); 这段代码就是获取 robovm 的线程池。Platform 主要提供了异步所需要的线程池,异步同步控制,而这个是一个抽象的接口,在 Retrofit 初始化时是可以指定其实现的。CallAdapter 就是上述接口。

4.invokeDefaultMethod:

  这个对应了 Java8 中 的 default 方 法 , 暂 时 没 有 实 现 , 会 抛 出UnSupportOperationException,也就是说你不可以调用接口中的 default 方法。

5.loadServiceMethod(method):

  加载 API 方法的实现,即加载动态代理,前面说过了,如果在 create 时已经解析过接口了的话,代理对象直接在缓存中找到。如果没有则需要在这个时候解析并且存储到缓存中,下次调用同样的接口就不需要重复解析了,毕竟业务解析大量用到了反射这种耗时操作。

6.ServiceMethod.Build():

  解析业务接口方法并且生成对应的动态代理。
  解析返回值类型: Utils.getRawType 从返回值的范型中扣出真正的业务类型,应为返回值一般不会直接写业务 Model,而是对异步任务的包裹,对 Callback 的封装。
  createResponseConverter 和 parseMethodAnnotation 开始创建 Http 请求,这时候需要解析方法上的 Annotation,这个 Annotation 包含了 URL,和请求方法。获取完了这些信息之后,这个方法就开始根据这些参数拼装完整的 URL。
  parseParameter 解析方法参数 ,获取 请 求 参数 。 这个方法主要就是调用了parseParameterAnnotation 解析参数列表上的注解,注解中包含了参数类型,参数名,Header,Path 等信息。参数类型也可以是 Form,Part 等复杂类型。
  createCallAdapter 上面说过了,Retrofit 只是一个业务解析器,组装器,诸如返回值的 JSON/XML 解析,Http 请求底层等等都是交给其他框架处理的,Adapter 就是抽象接口,createCallAdapter 就是根据配置进行工具组装,组装完毕,请求到解析一整套流程就可以顺利执行了。

作者:ganyao939543405 发表于2017/7/20 15:20:37 原文链接
阅读:143 评论:0 查看评论

Viewing all articles
Browse latest Browse all 5930

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>