当前位置: 首页 > article >正文

【Android】Retrofit创建实例源理

文章目录

    • Retrofit类
    • Builder内部类
    • baseUrl()
    • addConverterFactory()
    • client()

对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 对象,用于执行网络请求。

http://www.kler.cn/a/155423.html

相关文章:

  • request爬虫库的小坑
  • Ue5 umg学习(一)
  • Nginx中实现流量控制(限制给定时间内HTTP请求的数量)示例
  • WPF中MVVM工具包 CommunityToolkit.Mvvm
  • MySQL远程连接错误解决:Host is not allowed to connect to this MySQL server
  • scala的练习题
  • Flyway 数据库版本管理 | 专业解决方案
  • 31、LCD1602功能函数代码
  • AURIX TC芯片中DSU实现安全启动
  • Excel 分列功能
  • 20、Resnet 为什么这么重要
  • Go语言 值传递
  • 【蓝桥杯软件赛 零基础备赛20周】第6周——栈
  • 分析实现HarmonyOS中的Linux内核架构模式
  • 2312skia,17路径和api概述
  • 【go语言开发】loglus日志框架的使用
  • mysql8.0 提取json数据转为行
  • 基于SpringBoot+Vue实现的前后端分离课程管理系统
  • 树与二叉树堆:经典OJ题集(2)
  • 2023.12.03 homework
  • 1094. 拼车 --力扣 --JAVA
  • PostgreSQL日志中的SQL记录时机 —— log_statement 和 log_min_duration_statement
  • Session 与 JWT 的对决:谁是身份验证的王者? (下)
  • 中序和前/后序遍历构造二叉树———通用做法
  • 15个Pandas代码片段助力数据分析
  • MySQL索引:优化数据访问的双面剑