【Android】Retrofit创建实例源理

对retrofit的创造实例过程进行源码剖析。

在说之前,介绍一个api,用于判断对象是否为空,然后执行,否则抛出异常,该api在下边很多地方都会出现:

    public static <T> T requireNonNull(T obj, String message) {
   
        if (obj == null)
            throw new NullPointerException(message);
        return obj;
    }
//用法:Objects.requireNonNull(obj, "obj == null");

Retrofit类

public final class Retrofit {
   
  // 网络请求配置对象(对网络请求接口中方法注解进行解析后得到的对象)
  // 作用:存储网络请求相关的配置,如网络请求的方法、数据转换器、网络请求适配器、网络请求工厂、基地址等
  private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();

  // Call.Factory 实例,用于生产网络请求器,发送网络请求。默认使用的是okhttp
  final okhttp3.Call.Factory callFactory;
  
  // API 的基础 URL 地址
  final HttpUrl baseUrl;
  
  // Converter.Factory 实例的列表,用于序列化和反序列化对象
  final List<Converter.Factory> converterFactories;
  
  // CallAdapter.Factory 实例的列表,用于支持不同于 Call 的返回类型
  final List<CallAdapter.Factory> callAdapterFactories;
  
  // 回调方法执行的 Executor
  final @Nullable Executor callbackExecutor;
  
  // 是否在创建 Retrofit 实例时进行配置验证
  final boolean validateEagerly;
  
  省略构造函数
    ...

Builder内部类

Builder类的成员变量与Retrofit类的成员变量是对应的,所以Retrofit类的成员变量基本上是通过Builder类的链式调用方法进行配置

public static final class Builder {
   
    private Platform platform; // 平台对象
    private okhttp3.Call.Factory callFactory; // 网络请求的 Call.Factory
    private HttpUrl baseUrl; // API 的基础 URL 地址
    private List<Converter.Factory> converterFactories = new ArrayList<>(); // 数据转换器工厂列表
    private List<CallAdapter.Factory> adapterFactories = new ArrayList<>(); // 适配器工厂列表
    private Executor callbackExecutor; // 回调方法执行器
    private boolean validateEagerly; // 是否提前验证

    // 构造函数
    public Builder() {
   
        this(Platform.get()); // 使用 Platform.get() 初始化 Builder↓
    }
    
    // 获取平台对象
    static Platform get() {
   
        return PLATFORM;
    }

    // Builder 的有参构造函数
    public Builder(Platform platform) {
   
        this.platform = platform; // 设置平台对象(Android)
      // converterFactories是一个存放数据转换器Converter.Factory的数组,下边添加数据转换器
        converterFactories.add(new BuiltInConverters()); 
      // 初始化数据转换器工厂,
      // BuiltInConverters是一个内置的数据转换器工厂(继承Converter.Factory类)
    }
}

那么我们调用构造函数时,就会调用有参构造函数,参数最终是PLATFORM,这个参数在Platform类中已经定义:

class Platform {
   
  private static final Platform PLATFORM = findPlatform();

  static Platform get() {
   
    return PLATFORM;
  }

  // 查找适合的平台
  private static Platform findPlatform() {
   
    // 判断当前平台是否为 Dalvik(Android)
    return "Dalvik".equals(System.getProperty("java.vm.name"))
        ? new Android() // 如果是 Android 平台,则返回 Android 对象
        : new Platform(true); // 否则返回一个默认的 Platform 对象
  }

  /*下面的可以不用看,直到内部类Android*/
  
  // 是否支持 Java 8 类型
  private final boolean hasJava8Types;
  // MethodHandle 的构造函数
  private final @Nullable Constructor<Lookup> lookupConstructor;

  // 构造函数
  Platform(boolean hasJava8Types) {
   
    this.hasJava8Types = hasJava8Types;
    // 初始化 lookupConstructor
    Constructor<Lookup> lookupConstructor = null;
    if (hasJava8Types) {
   
      try {
   
        // 获取 MethodHandle 的构造函数
        lookupConstructor = Lookup.class.getDeclaredConstructor(Class.class, int.class);
        lookupConstructor.setAccessible(true); // 设置为可访问
      } catch (NoClassDefFoundError ignored) {
   
        // 对于 Android API 24 或 25,Lookup 类不存在,无法调用默认方法
      } catch (NoSuchMethodException ignored) {
   
        // 假设 JDK 14+,修复了默认方法的问题
      }
    }
    this.lookupConstructor = lookupConstructor;
  }

  // 获取默认的回调方法执行器
  @Nullable
  Executor defaultCallbackExecutor() {
   
    return null;
  }

  // 获取默认的网络请求适配器工厂列表
  List<? extends CallAdapter.Factory> defaultCallAdapterFactories(
      @Nullable Executor callbackExecutor) {
   
    DefaultCallAdapterFactory executorFactory = new DefaultCallAdapterFactory(callbackExecutor);
    return hasJava8Types
        ? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
        : singletonList(executorFactory);
  }

  // 获取默认的网络请求适配器工厂列表的大小
  int defaultCallAdapterFactoriesSize() {
   
    return hasJava8Types ? 2 : 1;
  }

  // 获取默认的数据转换器工厂列表
  List<? extends Converter.Factory> defaultConverterFactories() {
   
    return hasJava8Types ? singletonList(OptionalConverterFactory.INSTANCE) : emptyList();
  }

  // 获取默认的数据转换器工厂列表的大小
  int defaultConverterFactoriesSize() {
   
    return hasJava8Types ? 1 : 0;
  }

  // 判断方法是否为默认方法
  @IgnoreJRERequirement // 仅在 API 24+ 上调用
  boolean isDefaultMethod(Method method) {
   
    return hasJava8Types && method.isDefault();
  }

  // 调用默认方法
  @IgnoreJRERequirement // 仅在 API 26+ 上调用
  @Nullable
  Object invokeDefaultMethod(Method method, Class<?> declaringClass, Object object, Object... args)
      throws Throwable {
   
    Lookup lookup =
        lookupConstructor != null
            ? lookupConstructor.newInstance(declaringClass, -1 /* trusted */)
            : MethodHandles.lookup();
    return lookup.unreflectSpecial(method, declaringClass).bindTo(object).invokeWithArguments(args);
  }

  // Android 平台的实现,继承自 Platform。
  //用于接收服务器返回数据后进行线程切换在主线程显示结果
  static final class Android extends Platform {
   
    Android() {
   
      super(Build.VERSION.SDK_INT >= 24);
    }

    // 获取默认的回调方法执行器
    @Override
    public Executor defaultCallbackExecutor() {
   
      return new MainThreadExecutor();
      // 返回一个默认的回调方法执行器
      // 作用:切换线程(子->>主线程),并在UI线程中执行回调方法
    }

    // 调用默认方法
    @Nullable
    @Override
    Object invokeDefaultMethod(
        Method method, Class<?> declaringClass, Object object, Object... args) throws Throwable {
   
      if (Build.VERSION.SDK_INT < 26) {
   
        throw new UnsupportedOperationException(
            "Calling default methods on API 24 and 25 is not supported");
      }
      return super.invokeDefaultMethod(method, declaringClass, object, args);
    }

    // Android 平台的主线程执行器
    static final class MainThreadExecutor implements Executor {
   
      private final Handler handler = new Handler(Looper.getMainLooper());
      // 该Handler是上面获取的与Android UI线程绑定的Handler 
      @Override
      public void execute(Runnable r) {
   
        handler.post(r);
        // 在UI线程进行对网络请求返回数据处理等操作。
      }
    }
  }
}

baseUrl()

我们通常调用该函数,填入的都是String类型:

    public Builder baseUrl(String baseUrl) {
   
      Objects.requireNonNull(baseUrl, "baseUrl == null");
      return baseUrl(HttpUrl.get(baseUrl));//转换
    }

我们可以看到他会跳转到baseUrl(HttpUrl baseUrl)方法,↓

    public Builder baseUrl(HttpUrl baseUrl) {
   
      Objects.requireNonNull(baseUrl, "baseUrl == null");
      List<String> pathSegments = baseUrl.pathSegments();//分割成几个路径碎片
      
      //检查是否以'/'结尾,否则抛出异常
      if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
   
        throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
      }
      this.baseUrl = baseUrl;
      return this;
    }

addConverterFactory()

    //存储 Converter.Factory
    private final List<Converter.Factory> converterFactories = new ArrayList<>();

    public Builder addConverterFactory(Converter.Factory factory) {
   
      converterFactories.add(Objects.requireNonNull(factory, "factory == null"));
      return this;
    }

这里用来把转换工厂放入Retrofit的集合中,我们一般在括号内填的是第三方库:GsonConverterFactory.create()

public final class GsonConverterFactory extends Converter.Factory {
   

  public static GsonConverterFactory create() {
   
    // 调用create()↓
    return create(new Gson()); ->>步骤2
  }


  public static GsonConverterFactory create(Gson gson) {
   
    return new GsonConverterFactory(gson); 
    // 创建了一个含有Gson对象实例的GsonConverterFactory ↓
  }

  
  private final Gson gson;
  
  private GsonConverterFactory(Gson gson) {
   
    if (gson == null) throw new NullPointerException("gson == null");
    this.gson = gson;
  }

Retrofit默认使用Gson进行解析

client()

    public Builder client(OkHttpClient client) {
   
      return callFactory(Objects.requireNonNull(client, "client == null"));
    }

    /**
     * Specify a custom call factory for creating {@link Call} instances.
     *
     * <p>Note: Calling {@link #client} automatically sets this value.
     */
    public Builder callFactory(okhttp3.Call.Factory factory) {
   
      this.callFactory = Objects.requireNonNull(factory, "factory == null");
      return this;
    }
    //当创建 Retrofit 实例时,会使用这个 callFactory 对象来创建 Call 对象,用于执行网络请求。

相关推荐

  1. 【Android】Retrofit创建实例

    2023-12-07 19:48:05       28 阅读
  2. AC63串口收发实例

    2023-12-07 19:48:05       22 阅读
  3. 武汉工大学python123实验——字符串

    2023-12-07 19:48:05       11 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-07 19:48:05       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-07 19:48:05       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-07 19:48:05       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-07 19:48:05       20 阅读

热门阅读

  1. 26.Oracle11g的数据装载

    2023-12-07 19:48:05       43 阅读
  2. Node.js 的 os 模块介绍

    2023-12-07 19:48:05       35 阅读
  3. Django回顾5

    2023-12-07 19:48:05       29 阅读
  4. docker安装达梦数据库并挂在数据卷

    2023-12-07 19:48:05       40 阅读
  5. HTTPS:保护网络通信安全的关键

    2023-12-07 19:48:05       46 阅读
  6. linux中xarray结构简析

    2023-12-07 19:48:05       40 阅读
  7. Pod 存活探针 livenessProbe

    2023-12-07 19:48:05       41 阅读
  8. sklearn 笔记:neighbors.NearestNeighbors 自定义metric

    2023-12-07 19:48:05       36 阅读
  9. 当内核有内存泄漏的时候

    2023-12-07 19:48:05       27 阅读
  10. 【Spark基础】-- 宽窄依赖

    2023-12-07 19:48:05       34 阅读
  11. 拥有一台服务器可以做些什么

    2023-12-07 19:48:05       41 阅读