Retrofit 拆轮子之构建流程分析
在使用 OkHttp 的时候,还是要自己构建 Request 的,我们的目的是请求一个 url 并拿到数据,构建流程不利于逻辑清晰,特别是当需要 Post 上传数据的时候。Square 显然是看到了这个问题,便推出了 Retrofit 来解决这个问题。
Retrofit 使用注解的方式来定义一个后端接口,在 运行时 解析,动态构建出请求逻辑并执行。有时候还是会遇上一些坑,所以最快捷的方式就是阅读它的源码,知道了内部逻辑,自然而然就知道了问题出在哪里。
这里基于 Retrofit:2.4.0-SNAPSHOT 分析
构建流程分析
Retrofit 简化请求的构建,使得网络请求就像简单的函数调用一样。这次就分析下面的案例:
interface MyService {
@GET("/user")
Observable<User> getUser();
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://example.com/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
MyService service = retrofit.create(MyService.class);
Observable<User> observable = service.getUser();- Retrofit:2.4.0-SNAPSHOT
请求流程概览
忽略前面 Retrofit 实例的配置和构建,直接分析后面的请求发起过程,下面是整个流程的概览图:

参照@stay4it 的流程图作了简化。
重要类剖析
ServiceMethod
JavaDoc 中的注释是这样的:Adapts an invocation of an interface method into an HTTP call。大概意思就是把我们定义的接口方法包装成一个 HTTP 请求。在构建一个 ServiceMethod 实例时会解析我们定义的接口方法,解析注解以及返回值等等并确定 CallAdapter 和 Converter。
CallAdapter
CallAdapter 是个接口,在 retrofit-calladapters 这个 module 下有它的实现类。这个类的作用是将一个 Call
public interface CallAdapter<R, T> {
Type responseType();
//核心方法
T adapt(Call<R> call);
abstract class Factory {
public abstract @Nullable CallAdapter<?, ?> get(Type returnType, Annotation[] annotations,
Retrofit retrofit);
}
}Converter
请求/响应体转换,将实例转换成 HTTP 能接受的形式,或者从 HTTP 中转换出想要的类型。在 retrofit-converters 这个 Module 下有它的一些实现类,如 GsonXXXBodyConverter,它能实现 Call
public interface Converter<F, T> {
T convert(F value) throws IOException;
abstract class Factory {
public @Nullable Converter<ResponseBody, ?> responseBodyConverter(Type type,
Annotation[] annotations, Retrofit retrofit) {
return null;
}
public @Nullable Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
return null;
}
public @Nullable Converter<?, String> stringConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
return null;
}
}
}OkHttpCall
对 OkHttp 的Call 进行了一个包装,然后完成一些 Call 的操作,这里的 Call 是指 okhttp3.Call。