美文网首页
看清Retrofit的本质,它做了什么

看清Retrofit的本质,它做了什么

作者: s1991721 | 来源:发表于2018-10-22 15:45 被阅读0次

android中较为火热的网络库当数OkHttp和Retrofit了,它们都来自Square,为什么同样的网络库要做两种?OkHttp与Retrofit之间又有什么联系?我们一步步,揭开Retrofit的源码看看它到底与OkHttp有什么区别!


Retrofit的使用与OkHttp有些许不同

OkHttp中需要请求的相关信息由Request对象承载

而在Retrofit中每一个请求由方法表示,方法的参数和注解信息为相关的请求信息,且方法必须定义在接口类中

异步请求 同步请求

同步请求时,不能够阻塞主线程

和OkHttpClient类有点类似,根据之前的经验直接进入Retrofit.Builder内部类中

    public Retrofit build() {
      if (baseUrl == null) {
        throw new IllegalStateException("Base URL required.");
      }

      okhttp3.Call.Factory callFactory = this.callFactory;
      if (callFactory == null) {
        callFactory = new OkHttpClient();
      }

      Executor callbackExecutor = this.callbackExecutor;
      if (callbackExecutor == null) {
        callbackExecutor = platform.defaultCallbackExecutor();
      }

      // Make a defensive copy of the adapters and add the default Call adapter.
      List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
      callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

      // Make a defensive copy of the converters.
      List<Converter.Factory> converterFactories =
          new ArrayList<>(1 + this.converterFactories.size());

      // Add the built-in converter factory first. This prevents overriding its behavior but also
      // ensures correct behavior when using converters that consume all types.
      converterFactories.add(new BuiltInConverters());
      converterFactories.addAll(this.converterFactories);

      return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
          unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
    }

通过构建者模式实例化Retrofit对象返回,build方法中做了初始化工作,几个关键的对象被实例化

  • baseUrl:网络请求的基地址

  • callFactory:okhttp中的okhttp3.Call.Factory类用于生成call对象的工厂,用于实际的网络请求

  • callbackExecutor:Executor类的实例化对象,由默认平台生成,用于任务执行的具体工人,但并不是所有都会用到!(这里挖个坑)

  • callAdapterFactories:集合类存放CallAdapter.Factory对象,区分callAdapter和Factories,callAdapter是call的适配器,Factories则是产生适配器的工厂们,注意复数形式

  • converterFactories:集合类存放Converter.Factory对象,区分converter和Factories,converter是类型转换器(如JSON与java对象间的转换),Factories则是生产converter的工厂们

创建的Retrofit对象持有以上几个变量

Retrofit中没有Request对象承载请求信息,转而使用接口

  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.adapt(okHttpCall);
          }
        });
  }

通过动态代理的方式,生成对应的接口对象

前面所说:每一个请求对应接口类中的一个方法。接口被动态代理生成接口对象,当接口对象调用其中的方法时意味着一次请求,由于接口对象是代理对象,那具体的方法执行由代理方法执行

即方法的执行进入代理方法内,代理方法返回call对象,和OkHttp一样是具体的请求,请求结果Response就是call通过execute、enqueue返回的。

咦?怎么这次到这就没了,OkHttp的时候不是深度阅读么,这次怎么是广度阅读了?

首先Retrofit不同于OkHttp是正儿八经的网络库,它只是OkHttp的应用封装,没有OkHttp的请求信息处理、路由、返回码处理、重连、重定向、Cache等众多的网络功能。看OkHttp源码时要深入到网络情况的各种细节,而对于Retrofit要从封装的角度看待源码,了解为什么作者这样封装,采用了这种设计模式的精妙之处在哪里。

封装的几大关键类

  • ServiceMethod 接口中每一个方法对应的实际对象
  • OkHttpCall Retrofit中的Call类,有请求相关的信息
  • okhttp3.Call.Factory 这是okhttp中的类,生产call的工厂,Retrofit默认值是OkHttpClient
  • Converter.Factory 转换类的工厂
  • CallAdapter.Factory call适配器的工厂,将call适配成不同的功能

网络请求时代理对象调用接口方法,生产call对象。call对象是serviceMethod将okHttpCall对象交给callAdapter适配得来的

这里以RxJavaCallAdapterFactory特定的CallAdapter.Factory来分析,它产生的是RxJavaCallAdapter类。

serviceMethod通过adapt方法将okHttpCall适配成rxCall,具体实现类是RxJavaCallAdapter

RxJavaCallAdapter

就是将call转换成observable类型,当call执行execute时

生产call

call是通过ServiceMethod中callFactory产生的

callFactory默认就是okHttpClient,代码中的RequestBuilder也是OkHttp中的类

至此原本的OkHttpCall经过RxJavaCallAdapter的适配和okHttpClient的生成,已经可以正常的发起请求了。

OkHttp网络库做了实际的网络请求取得response对象

response对象又使用serviceMethod中的converter对象(GsonConverterFactory生成的)转换成需要的类型返回


总结

1、ServiceMethod对应每一个请求,主要功能有:

  • 产生实际请求的okhttp3.Call对象
  • 适配okhttp3.Call对象
  • 将okhttp3.Call对象请求返回的response转换成java对象

2、OkHttpCall是Retrofit中的Call,有相关的网络功能,但其实际是okhttp3.Call的封装类,具体的网络请求都是由okhttp3.Call完成

至于以上三个类都是ServiceMethod内所持有的对象,通过接口中定义方法的具体参数,以泛型的方式传到具体的对象内持有。

此三类都是工厂模式中的工厂,实际的操作在工厂的产出类内部实现。

回到标题,Retrofit做了什么,就是对OkHttp的封装,将call封装成支持Rx(或其他的形式),并将response通过Gson(或其他序列化协议)转成泛型的实际java对象

填坑


前面挖了个坑callbackExecutor,大部分资料都是讲其用于线程间切换的,以及如何切换的,就是下图

但具体是怎么切换的?为什么call.enqueue的回调就默认回到主线程了?

文中使用了RxJavaCallAdapterFactory其实有些误导,我也不打算把这个答案写出来,给几个提示!

1、接口返回类型


2、call适配过程


3、CallAdapter选择的依据


RxJavaCallAdapterFactory ExecutorCallAdapterFactory

相关文章

  • 看清Retrofit的本质,它做了什么

    android中较为火热的网络库当数OkHttp和Retrofit了,它们都来自Square,为什么同样的网络库要...

  • 拆轮子系列:Retrofit2

    拆轮子系列:Retrofit2 [TOC] Retrofit本质上是对OkHttpClient网络交互的封装,它接...

  • Retrofit执行流程及源码解析

    Retrofit网络请求本质是OkHttp完成的,它仅仅是对网络请求接口的封装.Retrofit最外层通过建造者模...

  • Retrofit源码分析一 概览

    Retrofit源码分析一 概览 Retrofit的本质和与Okhttp的关系​ 说到Retrofit,免不...

  • Android-Retrofit+RxJava+OkHttp

    Retrofit Retrofit的本质 准确来说,Retrofit只是负责对网络请求接口的封装,真正的网络请求工...

  • 看清本质

    看清问题的本质,看清事情的本质,看清人的本质。 生活中有太多的东西需要我们看清其本质,为何?尽管我们相信美好,相信...

  • Android网络编程- 简要记录Retrofit的使用

    初识Retrofit网络框架,简要记录一下使用流程: 我理解的Retrofit Retrofit网络框架,本质上来...

  • 2018-07-10关于“时间”概念的简单思考

    李笑来说他是时间的朋友,我问“时间”是什么? 回答这个问题,我们首先的思路是看清是的本质是什么,它...

  • 本质

    什么才是事物的本质,怎么才能看清事物的本质,看清事情的模式,你对什么用心,什么就会反馈你结果,遇到自己不明白和想不...

  • 生活的本质就是看清它,然后依旧热爱它

    我,一位普通的不能再普通的女孩子,从幼儿园到大学,再到社会,遭受了无数的打击,小时候在学校里被欺负,长大后被社...

网友评论

      本文标题:看清Retrofit的本质,它做了什么

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