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