在使用 OkHttp 的时候,还是要自己构建 Request 的,我们的目的是请求一个 url 并拿到数据,构建流程不利于逻辑清晰,特别是当需要 Post 上传数据的时候。Square 显然是看到了这个问题,便推出了 Retrofit 来解决这个问题。

Retrofit 使用注解的方式来定义一个后端接口,在 运行时 解析,动态构建出请求逻辑并执行。有时候还是会遇上一些坑,所以最快捷的方式就是阅读它的源码,知道了内部逻辑,自然而然就知道了问题出在哪里。

这里基于 Retrofit:2.4.0-SNAPSHOT 分析

构建流程分析

Retrofit 简化请求的构建,使得网络请求就像简单的函数调用一样。这次就分析下面的案例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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转换成一个 T,比如 Call-> Observable,从而直接拿到想要的类型值。

1
2
3
4
5
6
7
8
9
10
11
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-> Call的转换。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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。