【Android】Retrofit2.0 源码解析

1,053 阅读2分钟
  • Retrofit.Builder()
    看看new Retrofit.Builder()调用的代码

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

    Platform.get()又是什么?抱着一贯的好奇,点进去看看。主要代码如下

    private static final Platform PLATFORM = findPlatform();
    static Platform get() {
      return PLATFORM;
    }
    private static Platform findPlatform() {
      try {
          Class.forName("android.os.Build");
          if (Build.VERSION.SDK_INT != 0) {
          return new Android();
        }
        } catch (ClassNotFoundException ignored) {
        }
      try {
          Class.forName("java.util.Optional");
          return new Java8();
        } catch (ClassNotFoundException ignored) {
        }
      try {
          Class.forName("org.robovm.apple.foundation.NSObject");
          return new IOS();
        } catch (ClassNotFoundException ignored) {
        }
      return new Platform();
    }

    机智的你一定能看出来,主要就是这个findPlatform()方法。这里面的代码,就是判断当前运行的平台。可以看到里面有AndroidJava8IOS。等下,怎会有IOS,什么鬼(为什么会有IOS就交给你去研究了)。
    我们在Android上运行的话,就调用了return new Android();。进一步往下看,Android()是什么

    static class Android extends Platform {
      @Override public Executor defaultCallbackExecutor() {
        return new MainThreadExecutor();
      }
      @Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
        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重写了defaultCallbackExecutordefaultCallAdapterFactory方法。
    defaultCallbackExecutor:返回的是用于执行 Callback 的 线程池。可以看到MainThreadExecutor 获取了主线程的 Looper 并构造了一个主线程的 Handler,调用 Callback 时会将该请求 post 到主线程上去执行。这就解释了为什么请求后完成的回调都是在主线中。
    defaultCallAdapterFactory:将返回的适配类型默认为Call类型(如果使用RxJava的话,就可以通过配置.addCallAdapterFactory(RxJavaCallAdapterFactory.create())将配置类型改成Observable。)

  • .baseUrl("hcy.com/api/")
    public Builder baseUrl(String baseUrl) {
      checkNotNull(baseUrl, "baseUrl == null");
      HttpUrl httpUrl = HttpUrl.parse(baseUrl);
      if (httpUrl == null) {
        throw new IllegalArgumentException("Illegal URL: " + baseUrl);
      }
      return baseUrl(httpUrl);
    }
    public Builder baseUrl(HttpUrl baseUrl) {
      checkNotNull(baseUrl, "baseUrl == null");
      List pathSegments = baseUrl.pathSegments();
      if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
        throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
      }
      this.baseUrl = baseUrl;
      return this;
    }
    这里有两个重载的方法,创建了okhttp3HttpUrl 实例。
  • .addConverterFactory(GsonConverterFactory.create())
    public Builder addConverterFactory(Converter.Factory factory) {
      converterFactories.add(checkNotNull(factory, "factory == null"));
      return this;
    }
    往转换工厂集合中添加了我们指定的转换工厂,最后将返回的数据类型转换成对应的实体类对象的Converter类型。在我们的例子里面 GsonConverterFactory 将选用 GsonConverter 来转换。
  • .build();

    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 adapterFactories = new ArrayList<>(this.adapterFactories);
      adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
    
      // Make a defensive copy of the converters.
      List converterFactories = new ArrayList<>(this.converterFactories);
      return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
          callbackExecutor, validateEagerly);
    }

    看最后一句

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

    这里才是创建Retrofit对象的地方,之前的只是一些配置。里面的参数:
    callFactory(Call工厂):看到了吧callFactory = new OkHttpClient();,这里用的是okhttp3
    baseUrl(服务器基本地址):这个我们上面配置过;
    converterFactories(对象的序列号/反序列化组件):我们上面配置过。
    adapterFactories(适配类型)、callbackExecutor(执行 Callback 的线程池):从我们上面提到的platform中获取默认值。
    validateEagerly(标识):先不说,后面会用到