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

原文地址:https://blog.csdn.net/weixin_73871834/article/details/134769389

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_36958.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注