这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战」
介绍
Retrofit 是一个 RESTful 的 HTTP 网络请求框架的封装。
App应用程序通过 Retrofit 请求网络,实际上是使用 Retrofit 接口层封装请求参数、Header、Url 等信息,之后由 OkHttp 完成后续的请求操作 在服务端返回数据之后,OkHttp 将原始的结果交给 Retrofit,Retrofit根据用户的需求对结果进行解析。
网络请求的流程
- 通过解析 网络请求接口的注解 配置 网络请求参数
- 通过 动态代理 生成 网络请求对象
- 通过 网络请求适配器 将 网络请求对象 进行平台适配
- 通过 网络请求执行器 发送网络请求
- 通过 数据转换器 解析服务器返回的数据
- 通过 回调执行器 切换线程(子线程 ->>主线程)
- 用户在主线程处理返回结果
几大角色的作用
| 角色 | 作用 | 备注 |
|---|---|---|
| 网络请求执行器(Call) | 创建HTTP网络请求 | Retrofit默认为okhttp3.call |
| 网络请求适配器(CallAdapter) | 网络请求执行器call的适配器,将默认的网络请求执行器OkHttpCall转换成适合不同平台调用的网络请求执行器 | Retrofit支持Android,Rxjava,java8和Guava四个平台。 |
| 数据转换器(Converter) | 将返回数据解析成我们需要的数据类型 | Retrofit支持XML,Gson,JSON,protobuf |
| 回调执行器(CallBackExecutor) | 线程切换(子线程->主线程) | 将最后okhttp的请求结果通过callbackExecutor使用Handler异步回调传回主线程 |
网络适配器作用的理解:
一开始Retrofit只打算利用Okhttpcall通过ExecutorCallbackCall切换线程,但是后来发现使用Rxjava更加方便(不需要handler来切换线程),想要实现Rxjava,那就得睡用RxjavaCallAdapterFactoryCallAdapter将Okhttp转换成Rxjava(Scheduler)。好处是用最小的代价兼容来更多的平台。
使用
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://fanyi.youdao.com/") .addConverterFactory(GsonConverterFactory.create())
.build();
源码分析
public final class Retrofit {
//网络请求配置对象(对网络请求接口中方法注解进行解析后得到的对象)
private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();
//网络请求器的工厂
final okhttp3.Call.Factory callFactory;
//网络请求的url地址
final HttpUrl baseUrl;
//数据转换器工厂的集合
final List<Converter.Factory> converterFactories;
//网络请求适配器工厂的集合
final List<CallAdapter.Factory> callAdapterFactories;
//回调方法执行器
final @Nullable Executor callbackExecutor;
//标识位(是否提前对业务接口中的注解进行验证转换的标志位)
final boolean validateEagerly;
//构造函数
Retrofit(
okhttp3.Call.Factory callFactory,
HttpUrl baseUrl,
List<Converter.Factory> converterFactories,
List<CallAdapter.Factory> callAdapterFactories,
@Nullable Executor callbackExecutor,
boolean validateEagerly) {
this.callFactory = callFactory;
this.baseUrl = baseUrl;
this.converterFactories = converterFactories; // Copy+unmodifiable at call site.
this.callAdapterFactories = callAdapterFactories; // Copy+unmodifiable at call site.
this.callbackExecutor = callbackExecutor;
this.validateEagerly = validateEagerly;
}
}
- serviceMethod:包含所有网络请求信息的对象
- baseUrl:网络请求的url地址
- callFactory:网络请求工厂
- adapterFactories:网络请求适配器工厂的集合
- converterFactories:数据转换器工厂的集合
- callbackExecutor:回调方法执行器
builder类
public static final class Builder {
private final Platform platform;
private @Nullable okhttp3.Call.Factory callFactory;
private @Nullable HttpUrl baseUrl;
private final List<Converter.Factory> converterFactories = new ArrayList<>();
private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>();
private @Nullable Executor callbackExecutor;
private boolean validateEagerly;
Builder(Platform platform) {
this.platform = platform;
}
//构造方法
public Builder() {
this(Platform.get());
}
}
来到platform类中
class Platform {
private static final Platform PLATFORM = findPlatform();
static Platform get() {
return PLATFORM;
}
private static Platform findPlatform() {
return "Dalvik".equals(System.getProperty("java.vm.name"))
? new Android() //
: new Platform(true);
}
}
static final class Android extends Platform {
Android() {
super(Build.VERSION.SDK_INT >= 24);
}
@Override
public Executor defaultCallbackExecutor() {
//返回一个默认的回调方法执行器
return new MainThreadExecutor();
}
@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);
}
static final class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override
public void execute(Runnable r) {
handler.post(r);
}
}
}
切换线程的流程:
- 回调ExecutorCallAdapterFactory生成了一个ExecutorCallbackCall对象
- 通过调用ExecutorCallbackCall.enqueue(CallBack)从而调用MainThreadExecutor的execute()通过handler切换到主线程
baseUrl
public Builder baseUrl(String baseUrl) {
Objects.requireNonNull(baseUrl, "baseUrl == null");
return baseUrl(HttpUrl.get(baseUrl));
}
public Builder baseUrl(HttpUrl baseUrl) {
Objects.requireNonNull(baseUrl, "baseUrl == null");
//把url参数分割成几个路径
List<String> pathSegments = baseUrl.pathSegments();
//检测最后一个碎片来检查URL参数是不是以"/"结尾,如果不是则抛出异常
if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
}
this.baseUrl = baseUrl;
return this;
}
addConverterFactory(GsonConverterFactory.create())
public final class GsonConverterFactory extends Converter.Factory {
public static GsonConverterFactory create() {
//创建gson对象
return create(new Gson());
}
@SuppressWarnings("ConstantConditions") // Guarding public API nullability.
public static GsonConverterFactory create(Gson gson) {
if (gson == null) throw new NullPointerException("gson == null");
//创建了一个含有Gson对象实例的GsonConverterFactory
return new GsonConverterFactory(gson);
}
private final Gson gson;
private GsonConverterFactory(Gson gson) {
this.gson = gson;
}
...
}
GsonConverterFactory.creat()是创建了一个含有Gson对象实例的GsonConverterFactory
//将上面创建的GsonConverterFactory放入到 converterFactories数组
public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(Objects.requireNonNull(factory, "factory == null"));
return this;
}
用于创建一个含有Gson对象实例的GsonConverterFactory并放入到数据转换器工厂converterFactories里
build()
public Retrofit build() {
//判断baseUrl
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
//配置网络请求执行器(callFactory)
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
//配置回调方法执行器
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
//配置网络请求适配器工厂
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
// 向该集合中添加了步骤2中创建的CallAdapter.Factory请求适配器(添加在集合器末尾) callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
//配置数据转换器工厂
List<Converter.Factory> converterFactories =
new ArrayList<>(
1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());
// Add the built-in converter factory first. This prevents overriding its behavior but also
// ensures correct behavior when using converters that consume all types.
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
converterFactories.addAll(platform.defaultConverterFactories());
// 最终返回一个Retrofit的对象,并传入上述已经配置好的成员变量
return new Retrofit(
callFactory,
baseUrl,
unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories),
callbackExecutor,
validateEagerly);
}
小结
Retrofit 使用建造者模式通过Builder类建立了一个Retrofit实例,具体创建细节是配置了:
-
平台类型对象(Platform - Android)
-
网络请求的url地址(baseUrl)
-
网络请求工厂(callFactory)
默认使用OkHttpCall
-
网络请求适配器工厂的集合(adapterFactories)
本质是配置了网络请求适配器工厂- 默认是ExecutorCallAdapterFactory
-
数据转换器工厂的集合(converterFactories)
本质是配置了数据转换器工厂
-
回调方法执行器(callbackExecutor)
默认回调方法执行器作用是:切换线程(子线程 - 主线程)
由于使用了建造者模式,所以开发者并不需要关心配置细节就可以创建好Retrofit实例。
在创建Retrofit对象时,你可以通过更多更灵活的方式去处理你的需求,如使用不同的Converter、使用不同的CallAdapter,这也就提供了你使用RxJava来调用Retrofit的可能。