美文网首页安卓开发博客
Android Retrofit2 源码分析(一)—— Retr

Android Retrofit2 源码分析(一)—— Retr

作者: JzyCc | 来源:发表于2019-02-26 01:18 被阅读85次

    Retrofit2 简介

    做为当前 Android 最主流的网络框架(我个人认为)。

    它基于 OkHttp3(square 的代表作) 做了十分优雅的封装,同时它作为大名鼎鼎的 square 公司的产品,我就不详细说它对 OkHttp3 的封装做到啥地步了
    (^ _ ^")。

    它可以通过十分简单的配置,来很好的满足各种业务场景,比如说可以使用自定义的适配器,转换器(这里最重要的是它可以和 RxJava 完美的相结合),代码简直优雅了十倍不止,同时它的使用也十分简单,可以通过不同的注解来定制一个 request...

    它的功能我也不多说了,上面说的可能有点夸张,但我做为一个 Android 开发的小白那是对它推崇至极,赞不绝口!

    接下来我将对如何构建一个 Retrofit 来做一个分析。

    Retrofit 简单用例

    apiService = new Retrofit.Builder().client(OkHttpManager.getInstance())
                        .addConverterFactory(GsonConverterFactory.create())
                        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                        .baseUrl(ApiSetting.SERVER_URL)
                        .build()
                        .create(ApiService.class);
    

    以上是我自己一个项目中创建 Retrofit 服务代理的代码,这里我们就根据这个流程,具体的去分析 Retrofit 的实现原理。

    其实在 build() 方法之前,无非都是做一些配置,所以我们将重点放在 build() 方法和 creat() 方法中。

    走进源码

    build() 方法

    先看源码

        public Retrofit build() {
          //如果 baseUrl 为空,那么抛出异常(Url都为空了,那还访问啥)
          if (baseUrl == null) {
            throw new IllegalStateException("Base URL required.");
          }
          //这里的 callFactory,就是我们上面示例中的自定义的 okhttp client, 
          //如果我们配置自定义的 client 的话,那么这里直接 new 一个默认的 client    
          okhttp3.Call.Factory callFactory = this.callFactory;
          if (callFactory == null) {
            callFactory = new OkHttpClient();
          }
          //这里则配置执行后的回调,我的示例中并没有配置  
          Executor callbackExecutor = this.callbackExecutor;
          if (callbackExecutor == null) {
            //这里跟 Builder 的时候有关,如果是 Android 环境下,那么会返回一个默认的 CallbackExecutor
            callbackExecutor = platform.defaultCallbackExecutor();
          }
    
          // Make a defensive copy of the adapters and add the default Call adapter.
          //这里就是我们配置的适配器,在示例中,我添加了RxJava 的相关适配器
          List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
          //添加完我们添加的适配器 后会自动添加必须的适配器,这里的设置的回调便是上面的 callbackExecutor
          callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
    
          // Make a defensive copy of the converters.
          
          //这里就是添加变流器的流程了,类似于适配器的添加,我们这里添加了 Gson 的相关转换器
          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);
    
          //这里依据我们配置的各种参数来生成一个 retrofit 的实例    
          return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
              unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
        }
    

    build 的流程非常简单,跟我们平常使用构造者模式的流程差不多,根据一系列的配置,最后在 build 方法中根据用户的配置和默认的设置创建出一个可以符合用户需求的对象。

    接下来我们来看下,Retrofit 为我们添加的默认功能都做了什么。

    默认添加的适配器

    build() 方法中为我们添加了默认的适配器

    callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
    

    这里传入了上面创建的 callbackExecutor,我们点进去看一下。

      CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
        // 如果 callbackExecutor 不为空,那么创建一个 ExecutorCallAdapterFactory
        if (callbackExecutor != null) {
          return new ExecutorCallAdapterFactory(callbackExecutor);
        }
        // 不然返回 DefaultCallAdapterFactory
        return DefaultCallAdapterFactory.INSTANCE;
      }
    

    这里对之前传入的 callbackExecutor 做了判空,并返回不同结果,我们再回去看下 callbackExecutor 的创建。

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

    如果我们没有配置 callbackExecutor 的话,系统就会调用 platform.defaultCallbackExecutor()

    不说了,再进去看下!

      @Nullable Executor defaultCallbackExecutor() {
       return null;
     }
    

    纳尼?返回的是 null,其实不是,这里我们先去看 Builder() 方法

        public Builder() {
          this(Platform.get());
        }
    

    这里调用了 Platform.get() 方法

      private static final Platform PLATFORM = findPlatform();
    
      static Platform get() {
        return PLATFORM;
      }
    

    PLATFORM 是调用了 findPlatform() 方法

      private static Platform findPlatform() {
        try {
          Class.forName("android.os.Build");
          if (Build.VERSION.SDK_INT != 0) {
            //这里可以看到 new 了一个 Androdi 对象
            return new Android();
          }
        } catch (ClassNotFoundException ignored) {
        }
        try {
          Class.forName("java.util.Optional");
          return new Java8();
        } catch (ClassNotFoundException ignored) {
        }
        return new Platform();
      }
    
      static class Android extends Platform {
       //在 Android 环境下,调用 platform.defaultCallbackExecutor() 就是这里
        @Override public Executor defaultCallbackExecutor() {
          return new MainThreadExecutor();
        }
        @Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
          if (callbackExecutor == null) throw new AssertionError();
          return new ExecutorCallAdapterFactory(callbackExecutor);
        }
    
        static class MainThreadExecutor implements Executor {
          private final Handler handler = new Handler(Looper.getMainLooper());
    
          @Override public void execute(Runnable r) {
            handler.post(r);
          }
        }
      }
    

    可以看到调用 platform.defaultCallbackExecutor() 的话,会生成 MainThreadExecutor

    所以我们在 Android 中使用的话,一般不会返回 DefaultCallAdapterFactory.INSTANCE

    但是 DefaultCallAdapterFactory 的代码十分简单,我们可以去了解下。

    那我们先看下 DefaultCallAdapterFactory 的作用。

    DefaultCallAdapterFactory

    /**
     * Creates call adapters for that uses the same thread for both I/O and application-level
     * callbacks. For synchronous calls this is the application thread making the request; for
     * asynchronous calls this is a thread provided by OkHttp's dispatcher.
     */
    final class DefaultCallAdapterFactory extends CallAdapter.Factory {
      static final CallAdapter.Factory INSTANCE = new DefaultCallAdapterFactory();
    
      @Override
      public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
        //如果我们 ApiService 接口中请求中返回的类型不是 Call 对象,那么就返回 null
        if (getRawType(returnType) != Call.class) {
          return null;
        }
        
        //1
        final Type responseType = Utils.getCallResponseType(returnType);
        return new CallAdapter<Object, Call<?>>() {
          @Override public Type responseType() {
            return responseType;
          }
    
          @Override public Call<Object> adapt(Call<Object> call) { 
            //直接返回 call
            return call;
          }
        };
      }
    }
    

    对于这段代码,先看它的注释,大致意思是回调和请求在同一线程,如果是异步请求,这个线程有 OkHttp 提供。

    然后我们再去看下注释 1 的 Utils.getCallResponseType(returnType) 方法作用

      static Type getCallResponseType(Type returnType) {
        // 这里对返回类型做了判断,如果不是 Call<Foo> 或者 Call<? extent Foo>,那么就抛出异常。
        if (!(returnType instanceof ParameterizedType)) {
          throw new IllegalArgumentException(
              "Call return type must be parameterized as Call<Foo> or Call<? extends Foo>");
        }
        // 返回获取到的返回值类型,以便后续 Conveeter 做类型转换
        return getParameterUpperBound(0, (ParameterizedType) returnType);
      }
    
    

    现在可以知道之前注释1 中的代码是用来获取请求返回值类型的。

    DefaultCallAdapterFactory 作用总结

    根据上面的分析,可以知道 DefaultCallAdapterFactory 中 回调和请求在同一线程,如果是异步请求,这个线程由 OkHttp 提供,而且对获取到的 Call 不做处理,直接返回。

    接下来去分析下 ExecutorCallAdapterFactory, 因为我们使用的时候,它才是默认的 CallAdapter。

    ExecutorCallAdapterFactory

    final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
      final Executor callbackExecutor;
    
      ExecutorCallAdapterFactory(Executor callbackExecutor) {
        this.callbackExecutor = callbackExecutor;
      }
    
      @Override
      public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
        if (getRawType(returnType) != Call.class) {
          return null;
        }
        final Type responseType = Utils.getCallResponseType(returnType);
        return new CallAdapter<Object, Call<?>>() {
          @Override public Type responseType() {
            return responseType;
          }
    
          @Override public Call<Object> adapt(Call<Object> call) {
            //1
            return new ExecutorCallbackCall<>(callbackExecutor, call);
          }
        };
      }
      ······
     }
    

    基本上和 DefaultCallAdapterFactory 一样,有了上面 DefaultCallAdapterFactory 的源码分析,这里就不多做介绍,唯一不同的是 adapt 方法中,
    它 new 了一个 ExecutorCallbackCall 对象,这里就是请求之后的回调,关于这里具体的内容,我打算在之后的 Retrofit 动态代理相关的内容去说,我们现在只需要知道它的作用就好了。

    默认添加的 转换器(变流器)

    接下来我们来看下,Retrofit 为我们添加的,而且特意添加到第一个位置的 BuiltInConverter。

    BuiltInConverter

      @Override
      public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
          Retrofit retrofit) {
        //如果返回数据的类型是 ResponseBody
        if (type == ResponseBody.class) {
          //这里根据数据处理是在 streaming 还是 buffer中做了判断,因为两者处理方式不同,所以分开处理。
          return Utils.isAnnotationPresent(annotations, Streaming.class)
              ? StreamingResponseBodyConverter.INSTANCE
              : BufferingResponseBodyConverter.INSTANCE;
        }
        //这一步的意图在于安全退出相关操作
        if (type == Void.class) {
          return VoidResponseBodyConverter.INSTANCE;
        }
        return null;
      }
    
      @Override
      public Converter<?, RequestBody> requestBodyConverter(Type type,
          Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
        //这里判断请求的类型是不是 OkHttp 中的 RequestBody,因为 Retrofit 就是对 OkHttp 做了十分棒的封装。 
        if (RequestBody.class.isAssignableFrom(Utils.getRawType(type))) {
          return RequestBodyConverter.INSTANCE;
        }
        return null;
      }
    

    这里我直接贴了 BuiltInConverter 唯二的方法,一个做为返回 body 的处理(responseBodyConverter),一个做为请求 body 的处理(requestBodyConverter)。

    两者其实都是对数据的类型或者环境做了判断,并给予不同的处理方式。

    以上涉及到的各种 Converter 都是 BuiltInConverter 的内部类,作用都跟名字一样清晰,代码也十分简单,没什么复杂的操作,我这里贴一下就不详解了,如下。

    static final class VoidResponseBodyConverter implements Converter<ResponseBody, Void> {
        static final VoidResponseBodyConverter INSTANCE = new VoidResponseBodyConverter();
    
        @Override public Void convert(ResponseBody value) {
          value.close();
          return null;
        }
      }
    
      static final class RequestBodyConverter implements Converter<RequestBody, RequestBody> {
        static final RequestBodyConverter INSTANCE = new RequestBodyConverter();
    
        @Override public RequestBody convert(RequestBody value) {
          return value;
        }
      }
    
      static final class StreamingResponseBodyConverter
          implements Converter<ResponseBody, ResponseBody> {
        static final StreamingResponseBodyConverter INSTANCE = new StreamingResponseBodyConverter();
    
        @Override public ResponseBody convert(ResponseBody value) {
          return value;
        }
      }
    
      static final class BufferingResponseBodyConverter
          implements Converter<ResponseBody, ResponseBody> {
        static final BufferingResponseBodyConverter INSTANCE = new BufferingResponseBodyConverter();
    
        @Override public ResponseBody convert(ResponseBody value) throws IOException {
          try {
            // Buffer the entire body to avoid future I/O.
            return Utils.buffer(value);
          } finally {
            value.close();
          }
        }
      }
    
      static final class ToStringConverter implements Converter<Object, String> {
        static final ToStringConverter INSTANCE = new ToStringConverter();
    
        @Override public String convert(Object value) {
          return value.toString();
        }
      }
    

    BuiltInConverter 作用总结

    其实它就是起到一个统筹的作用,做为 Retrofit 的内置 Converter,它根据需要处理的对象的类型以及环境不同来调用相适应的 Converter 来处理对应的任务。

    Retroift 的 构造方法

    其实到这里,我们已经差不多分析完了 Retrofit 默认配置的一些模块,我们回到 build() 方法中的最后一步。

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

    这里就是创建了一个 retrofit 实例

      Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
          List<Converter.Factory> converterFactories, List<CallAdapter.Factory> callAdapterFactories,
          @Nullable Executor callbackExecutor, boolean validateEagerly) {
        this.callFactory = callFactory;
        this.baseUrl = baseUrl;
        this.converterFactories = converterFactories; // Copy+unmodifiable at call site.
        this.callAdapterFactories = callAdapterFactories; // Copy+unmodifiable at call site.
        this.callbackExecutor = callbackExecutor;
        this.validateEagerly = validateEagerly;
      }
    
    

    到最后很简单,将配置好的参数都做为 Retrofit 构造时的初始值。

    最后 Retrofit 是如何运用我们配置好的适配器,转换器等等工具呢。

    还记得简单用例中最后的 create() 方法吗,Retrofit 在这个方法中,使用动态代理创建了一个代理供我们使用,而我们配置的这些适配器转换器等工具将在这里使用,Retrofit 会很智能的根据这些参数来生成我们想要的代理,我们只需要负责用就好了。

    总结

    这就是 Retrofit 关于 build 的源码分析,后面我会再深入到 create() 方法中,去看一下 Retrofit 最为核心的代码,是如何实现的。

    Android Retrofit2 源码分析(二)—— Retrofit 的动态代理

    相关文章

      网友评论

        本文标题:Android Retrofit2 源码分析(一)—— Retr

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