Retrofit 源码

与 OkHttp 的区别

封装不同:
Retrofit 实际上是基于 OkHttp 实现的并封装了具体的请求,线程切换以及数据转换。
Retrofit 通过使用代理,外观,策略模式对 OkHttp 进行了封装。
OkHttp 是基于 Http 协议封装的一套请求客户端

职责不同:
Retrofit 主要负责应用层面的封装,面向开发者,方便使用,比如请求参数,响应数据的处理,错误处理等等。
OkHttp 主要负责 socket 部分的优化与封装,比如网络访问,多路复用,buffer 缓存,数据压缩等等。

Retrofit 的创建过程

Retrofit 是通过建造者模式构建出来的,查看其 Builder 方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public Builder() {
this(Platform.get());
}


// Platform 的 get 方法最终调用的是 findPlatform()
private static Platform findPlatform() {
try {
Class.forName("android.os.Build");
if (Build.VERSION.SDK_INT != 0) {
return new Android();
}
} catch (ClassNotFoundException ignored) {
}
return new Platform(true);
}

查看其 build 方法,会做一些默认的初始化工作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public Retrofit build() {
if (baseUrl == null) {
// baseUrl 必须指定
throw new IllegalStateException("Base URL required.");
}
// callFactory 默认为 this.callFactory(构建 Retrofit 时调用 callFactory 方法所传进来的)。
// 所以,如果需要对 OkHttpClient 进行设置,可调用 callFactory 方法将其传进去。
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
// 如果没有设置 callFactory,则直接创建 OkHttpClient。
callFactory = new OkHttpClient();
}

Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
// callbackExecutor 用于将回调传递到 UI 线程。
callbackExecutor = platform.defaultCallbackExecutor();
}

// callAdapterFactories 主要用于存储对 Call 进行转化的对象
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));

// converterFactories 主要用于存储转化数据对象
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());

return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
}

Call 的创建过程

1
2
// 通过 retrofit 实例来生成接口的动态代理对象 
INetApiService iNetApiService = retrofit.create(INetApiService.class);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// class:Retrofit
public <T> T create(final Class<T> service) {
// 验证接口是否合理,保证了它是一个接口并且它和它继承的类中没有范型参数。
// 之后如果在 Retrofit 创建时设置 validateEagerly 为 true 的话,会对 Service 中所有非平台独有且非static 的方法通过 loadServiceMethod 方法提前进行处理。
validateServiceInterface(service);
// 返回了一个 Proxy.newProxyInstance 动态代理对象,当调用接口中的方法时,最终会调用 InvocationHandler() 的 invoke() 。通过动态代理构建代理对象。
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
// 真正负责生产 Call 网络工作对象的。
new InvocationHandler() {
private final Platform platform = Platform.get();
private final Object[] emptyArgs = new Object[0];

// 参数一:代理对象。参数二:调用的方法。参数三:方法的参数。
@Override
public @Nullable Object invoke(Object proxy, Method method,
@Nullable Object[] args) throws Throwable {
// Object 类的方法照常调用
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
// 如果是对应平台本身的类就有的方法,照常调用
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
// 否则通过 loadServiceMethod 方法获取到对应 Method 并 invoke
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}
});
}

说明 Retrofit 不是在创建 Service 接口对应对象时就立即对所有该接口中的所有方法都进行注解的解析,而是采用了在方法被调用时才进行注解的解析这种懒加载的思想。接下来查看其 loadServiceMethod():

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// class:Retrofit
// 为了避免多次对方法的注解进行处理,采用了一个 serviceMethodCache 对解析后的 ServiceMethod 进行缓存。
private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();

ServiceMethod<?> loadServiceMethod(Method method) {
// 首先它会采用 Double Check 的方式尝试从 serviceMethodCache 缓存中获取 ServiceMethod 对象,如果获取不到则通过 ServiceMethod.parseAnnotations 方法对该 Method 的注解进行处理并将得到的 ServiceMethod 对象加入了缓存。
ServiceMethod<?> result = serviceMethodCache.get(method);
if (result != null) return result;

synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
// 查看 ServiceMethod,其 parseAnnotations() 是如何对方法的注解进行解析的。
result = ServiceMethod.parseAnnotations(this, method);
serviceMethodCache.put(method, result);
}
}
return result;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
abstract class ServiceMethod<T> {
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
// 通过 RequestFactory.parseAnnotations 方法对注解解析并获得了一个 RequestFactory 对象。
RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);

Type returnType = method.getGenericReturnType();
if (Utils.hasUnresolvableType(returnType)) {
throw methodError(method,
"Method return type must not include a type variable or wildcard: %s", returnType);
}
if (returnType == void.class) {
throw methodError(method, "Service methods cannot return void.");
}
// 通过 HttpServiceMethod.parseAnnotations 方法传入了 requestFactory 继续进行注解的解析并获得 ServiceMethod 对象。
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}

abstract @Nullable T invoke(Object[] args);
}
1
2
3
4
5
6
// class:RequestFactory.parseAnnotations()
// 主要作用就是完成对方法注解信息的解析,从而用于产生对应的 Request。
static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
// 它把 Method 传入 Builder 从而构建了一个新的 RequestFactory。
return new Builder(retrofit, method).build();
}
1
2
3
4
5
6
7
8
// Builder 中通过反射获取到 method 所包含的注解、参数包含的范型以及参数的注解。
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
this.methodAnnotations = method.getAnnotations();
this.parameterTypes = method.getGenericParameterTypes();
this.parameterAnnotationsArray = method.getParameterAnnotations();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
RequestFactory build() {
for (Annotation annotation : methodAnnotations) {
// 遍历方法注解,对方法的每个注解进行解析。
parseMethodAnnotation(annotation);
}
// ...异常的处理

// 对每个参数进行解析
int parameterCount = parameterAnnotationsArray.length;
parameterHandlers = new ParameterHandler<?>[parameterCount];
for (int p = 0, lastParameter = parameterCount - 1; p < parameterCount; p++) {
// 对每个参数调用了 parseParamter 方法解析为了 ParamterHandler 对象。
parameterHandlers[p] =
parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p], p == lastParameter);
}
// 异常的处理
if (relativeUrl == null && !gotUrl) {
throw methodError(method, "Missing either @%s URL or @Url parameter.", httpMethod);
}
if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
throw methodError(method, "Non-body HTTP method cannot contain @Body.");
}
if (isFormEncoded && !gotField) {
throw methodError(method, "Form-encoded method must contain at least one @Field.");
}
if (isMultipart && !gotPart) {
throw methodError(method, "Multipart method must contain at least one @Part.");
}

return new RequestFactory(this);
}

查看 parseMethodAnnotation() ,实际上就是对每一种 HTTP 所支持的类型进行了支持,获取到了对应注解中的 url,并调用parseHttpMethodAndPath 对不同 HTTP 请求方式和 Path 进行了赋值,同时通过正则表达式保证了这个接口的 Path 中没有包含参数。同时对 Headers 注解则是通过 parseHeaders 将传递进来的 Headers 列表解析为了对应的 Headers 对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// class:RequestFactory
private void parseMethodAnnotation(Annotation annotation) {
if (annotation instanceof DELETE) {
parseHttpMethodAndPath("DELETE", ((DELETE) annotation).value(), false);
} else if (annotation instanceof GET) {
parseHttpMethodAndPath("GET", ((GET) annotation).value(), false);
} else if (annotation instanceof HEAD) {
parseHttpMethodAndPath("HEAD", ((HEAD) annotation).value(), false);
} else if (annotation instanceof PATCH) {
parseHttpMethodAndPath("PATCH", ((PATCH) annotation).value(), true);
} else if (annotation instanceof POST) {
parseHttpMethodAndPath("POST", ((POST) annotation).value(), true);
} else if (annotation instanceof PUT) {
parseHttpMethodAndPath("PUT", ((PUT) annotation).value(), true);
} else if (annotation instanceof OPTIONS) {
parseHttpMethodAndPath("OPTIONS", ((OPTIONS) annotation).value(), false);
} else if (annotation instanceof HTTP) {
HTTP http = (HTTP) annotation;
parseHttpMethodAndPath(http.method(), http.path(), http.hasBody());
} else if (annotation instanceof retrofit2.http.Headers) {
String[] headersToParse = ((retrofit2.http.Headers) annotation).value();
if (headersToParse.length == 0) {
throw methodError(method, "@Headers annotation is empty.");
}
headers = parseHeaders(headersToParse);
} else if (annotation instanceof Multipart) {
if (isFormEncoded) {
throw methodError(method, "Only one encoding annotation is allowed.");
}
isMultipart = true;
} else if (annotation instanceof FormUrlEncoded) {
if (isMultipart) {
throw methodError(method, "Only one encoding annotation is allowed.");
}
isFormEncoded = true;
}
}

接着查看 HttpServiceMethod.parseAnnotations():

新版的 Retrofit 对 Kotlin 的协程进行了支持。HttpServiceMethod.parseAnnotations 的主要作用就是创建 CallAdapter 以及 Converter 对象,并构建对应 HttpServiceMethod

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// class:HttpServiceMethod.parseAnnotations()
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction;
boolean continuationWantsResponse = false;
boolean continuationBodyNullable = false;

Annotation[] annotations = method.getAnnotations();
Type adapterType;
if (isKotlinSuspendFunction) {
// 如果这个方法是 Kotlin 中的 suspend 方法,由于由协程实现,因此需要获取 Continuation 的范型参数,这个参数就是请求返回值的真正类型。
Type[] parameterTypes = method.getGenericParameterTypes();
// 获取 Continuation 的范型参数,它就是 suspend 方法的返回值类型
Type responseType = Utils.getParameterLowerBound(0,
(ParameterizedType) parameterTypes[parameterTypes.length - 1]);
// 如果 suspend 方法返回值是 Response,则说明它需要的是 Response 而不是具体的类型,那么将 continuationWantsResponse 置为 true;
if (getRawType(responseType) == Response.class && responseType instanceof ParameterizedType) {
// Unwrap the actual body type from Response<T>.
responseType = Utils.getParameterUpperBound(0, (ParameterizedType) responseType);
continuationWantsResponse = true;
} else {
// TODO figure out if type is nullable or not
// Metadata metadata = method.getDeclaringClass().getAnnotation(Metadata.class)
// Find the entry for method
// Determine if return type is nullable or not
}

adapterType = new Utils.ParameterizedTypeImpl(null, Call.class, responseType);
annotations = SkipCallbackExecutorImpl.ensurePresent(annotations);
} else {
// 如果不是 suspend 方法,则返回值的范型参数的类型就是请求返回值的真正类型(Call<ReturnType> 则 ReturnType 才是真正经过转换后需要的类型)。
adapterType = method.getGenericReturnType();
}
// 通过 createCallAdapter 方法创建 CallAdapter 对象,它是用于将 Call<ResponseT> 对象适配为需要的类型 ReturnT 对象的。
CallAdapter<ResponseT, ReturnT> callAdapter =
createCallAdapter(retrofit, method, adapterType, annotations);
// 拿到 CallAdapter 后,获取到了 Response 的类型,并进行了校验。
// responseType 返回数据的真实类型
Type responseType = callAdapter.responseType();
if (responseType == okhttp3.Response.class) {
throw methodError(method, "'"
+ getRawType(responseType).getName()
+ "' is not a valid response body type. Did you mean ResponseBody?");
}
if (responseType == Response.class) {
throw methodError(method, "Response must include generic type (e.g., Response<String>)");
}
// TODO support Unit for Kotlin?
if (requestFactory.httpMethod.equals("HEAD") && !Void.class.equals(responseType)) {
throw methodError(method, "HEAD method must use Void as response type.");
}

// 通过 createResponseConverter 方法获取 Converter 对象,它可以完成从 ResponseBody 到 Response 类型 ResponseT 的转换。
Converter<ResponseBody, ResponseT> responseConverter =
createResponseConverter(retrofit, method, responseType);

okhttp3.Call.Factory callFactory = retrofit.callFactory;
// 如果并非 Kotlin 的 suspend 方法,则直接传入 CallAdapter 及 Converter,创建 CallAdapted 对象。
// 否则根据 suspend 方法需要的是 Response 还是具体的类型,分别返回 SuspendForResponse 和 SuspendForBody 对象。
if (!isKotlinSuspendFunction) {
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
} else if (continuationWantsResponse) {
//noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForResponse<>(requestFactory,
callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter);
} else {
//noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForBody<>(requestFactory,
callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter,
continuationBodyNullable);
}
}

CallAdapter 是用于将Call对象适配为需要的类型 T 对象的。它的声明如下:

1
2
3
4
5
6
public interface CallAdapter<R, T> {
// 返回 Response 的类型
Type responseType();
// 将 Call<R> 转换为 T 类型
T adapt(Call<R> call);
}

它是通过 createCallAdapter() 创建的,createCallAdapter() 内部调用了 retrofit.callAdapter(),之后调用了 retrofit.nextCallAdapter():

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
Objects.requireNonNull(returnType, "returnType == null");
Objects.requireNonNull(annotations, "annotations == null");

int start = callAdapterFactories.indexOf(skipPast) + 1;
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
// 遍历 callAdapterFactories,尝试创建 CallAdapter
CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
// ...不存在对应的 CallAdapterFactory,抛出异常。
}

在创建 Retrofit 对象时,build() 中有一个默认的 CallAdapter 工厂 DefaultCallAdapterFactory它的优先级比所有自定义工厂要低,它在创建时会传入一个 Executor,看它的 get 方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@Override 
public @Nullable CallAdapter<?, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
if (!(returnType instanceof ParameterizedType)) {
throw new IllegalArgumentException(
"Call return type must be parameterized as Call<Foo> or Call<? extends Foo>");
}
final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType) returnType);

final Executor executor = Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class)
? null
: callbackExecutor;

return new CallAdapter<Object, Call<?>>() {
@Override
public Type responseType() {
return responseType;
}
// 在没有 Executor 时,它不对 Call 进行修改,在有指定 Executor 时,则会将其包装为 ExecutorCallbackCall。一般来说这个 Executor 就是创建 Retrofit 时指定的 callbackExecutor。
@Override
public Call<Object> adapt(Call<Object> call) {
return executor == null
? call
: new ExecutorCallbackCall<>(executor, call); // 用来指定调用 Callback 的线程的,从而使得 Callback 并不一定是在主线程被回调。
}
};
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// 实际上只是对 Callback 进行了包装,通过传递的 Executor 进行回调,从而对 callbackExecutor 进行支持。
static final class ExecutorCallbackCall<T> implements Call<T> {
final Executor callbackExecutor;
final Call<T> delegate;

ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
this.callbackExecutor = callbackExecutor;
this.delegate = delegate;
}

@Override
public void enqueue(final Callback<T> callback) {
Objects.requireNonNull(callback, "callback == null");

delegate.enqueue(new Callback<T>() {
@Override public void onResponse(Call<T> call, final Response<T> response) {
callbackExecutor.execute(() -> {
if (delegate.isCanceled()) {
// Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation.
callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
} else {
callback.onResponse(ExecutorCallbackCall.this, response);
}
});
}

@Override public void onFailure(Call<T> call, final Throwable t) {
callbackExecutor.execute(() -> callback.onFailure(ExecutorCallbackCall.this, t));
}
});
}
// ...
}

Converter 类,用于将类型 F 的数据转换为类型 T:

1
2
3
4
public interface Converter<F, T> {
@Nullable T convert(F value) throws IOException;
// ...
}

它是通过 createResponseConverter() (class:HttpServiceMethod)来创建,后续调用到了 nextResponseBodyConverter():

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// class:Retrofit
public <T> Converter<ResponseBody, T> nextResponseBodyConverter(
@Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
Objects.requireNonNull(type, "type == null");
Objects.requireNonNull(annotations, "annotations == null");

int start = converterFactories.indexOf(skipPast) + 1;
for (int i = start, count = converterFactories.size(); i < count; i++) {
// 这里与 CallAdapter 工厂类似,遍历创建 Retrofit 时传入的 Converter.Factory 列表,尝试进行创建,如果没有工厂能对其进行处理,抛出异常。(前面 Factory 的优先级更高)
Converter<ResponseBody, ?> converter =
converterFactories.get(i).responseBodyConverter(type, annotations, this);
if (converter != null) {
//noinspection unchecked
return (Converter<ResponseBody, T>) converter;
}
}
// ...没有找到对应的 ConverterFactory 进行处理,抛出异常。
}

Retrofit 中内置了两个 Converter.Factory:

  • BuiltInConverters:优先级比所有自定义工厂要高,以避免其他工厂覆盖它的方法。其中实现了多个转换器如将 ResponseBody 转换为 Void 或 Unit,将 Object 转换为 String 等。
  • OptionalConverterFactory:优先级比所有自定义工厂的优先级更低。通过 platform 获取到的 defaultConverterFactories,它是为了支持 Java 8 的 Optional 而实现的,Optional 是 Java 8 引入的用来解决空指针异常的类。

ServiceMethod 类是一个抽象类,需要子类 HttpServiceMethod 对 invoke 方法进行实现。

1
2
3
4
5
6
7
8
9
10
11
// class:HttpServiceMethod
@Override
final @Nullable ReturnT invoke(Object[] args) {
// 它构造了一个 OkHttpCall,
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}


// 然后通过 adapt 这个虚函数来实现对 Call 的转换。它的子类只需要实现 adapt 从而对 Call 进行转换即可。
protected abstract @Nullable ReturnT adapt(Call<ResponseT> call, Object[] args);

HttpServiceMethod 共有三个子类:

  • 并非使用协程的情况下的 CallAdapted 类:通过传递进来的 CallAdapter 对 Call 进行了转换。
  • 使用协程的情况下为了配合协程的 SuspendForResponse 类:首先根据传递进来的 Call 构造了一个参数为 ResponseContinuation 对象然后通过 Kotlin 实现的 awaitResponse 方法将 call 的 enqueue 异步回调过程封装为了一个 suspend 的函数。
  • 使用协程的情况下为了配合协程的 SuspendForBody 类:根据传递进来的 Call 构造了一个 Continuation 对象然后通过 Kotlin 实现的 await 或 awaitNullable方法将 call 的 enqueue 异步回调过程封装为了一个 suspend 的函数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public interface Call<T> extends Cloneable {

Response<T> execute() throws IOException;

void enqueue(Callback<T> callback);

boolean isExecuted();

void cancel();

boolean isCanceled();

Call<T> clone();

Request request();
}

如果没有传入 CalAdapter 的话,默认情况下返回的 Call 实际上是 OkHttpCall 对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// class:OkHttpCall
@Override public void enqueue(final Callback<T> callback) {
Objects.requireNonNull(callback, "callback == null");

okhttp3.Call call;
Throwable failure;
// 加锁,对执行状态进行设置,若不存在 rawCall 则调用 createRawCall 方法创建 okhttp3.Call 对象。
synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
executed = true;

call = rawCall;
failure = creationFailure;
if (call == null && failure == null) {
try {
call = rawCall = createRawCall();
} catch (Throwable t) {
throwIfFatal(t);
failure = creationFailure = t;
}
}
}

if (failure != null) {
callback.onFailure(this, failure);
return;
}
// 如果外界取消该任务,则调用 okhttp3.Call.cancel。
if (canceled) {
call.cancel();
}
// 通过 okhttp3.Call.enqueue 将消息入队
call.enqueue(new okhttp3.Callback() {
@Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
Response<T> response;
try {
// 获得结果后通过 parseResponse 进行解析
response = parseResponse(rawResponse);
} catch (Throwable e) {
throwIfFatal(e);
callFailure(e);
return;
}

try {
// 若获得 Response,则通过 parseResponse 方法对 Response 进行解析,解析完成后通过 onResponse 回调解析结果。
callback.onResponse(OkHttpCall.this, response);
} catch (Throwable t) {
throwIfFatal(t);
t.printStackTrace(); // TODO this is not great
}
}

@Override public void onFailure(okhttp3.Call call, IOException e) {
// 若请求失败,通过 callFailure 方法调用 onFailure 回调请求失败。
callFailure(e);
}

private void callFailure(Throwable e) {
try {
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable t) {
throwIfFatal(t);
t.printStackTrace(); // TODO this is not great
}
}
});
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// class:OkHttpCall
@Override public Response<T> execute() throws IOException {
okhttp3.Call call;
// 首先加锁后对执行状态进行设置,若不存在 rawCall 则调用 createRawCall方法创建 okhttp3.Call 对象。
synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
executed = true;

if (creationFailure != null) {
if (creationFailure instanceof IOException) {
throw (IOException) creationFailure;
} else if (creationFailure instanceof RuntimeException) {
throw (RuntimeException) creationFailure;
} else {
throw (Error) creationFailure;
}
}

call = rawCall;
if (call == null) {
try {
call = rawCall = createRawCall();
} catch (IOException | RuntimeException | Error e) {
throwIfFatal(e); // Do not assign a fatal error to creationFailure.
creationFailure = e;
throw e;
}
}
}
// 如果外界取消该任务,则调用 okhttp3.Call.cancel。
if (canceled) {
call.cancel();
}
// 若获得 Response,则通过 parseResponse 方法对 Response 进行解析并返回。
return parseResponse(call.execute());
}

okhttp3.Call 的创建:

1
2
3
4
5
6
7
private okhttp3.Call createRawCall() throws IOException {
okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}

它实际上是调用了 callFactorynewCall 方法进行创建,而传入的 okhttp3.Request 则是通过 requestFactory.create 创建的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// class:RequestFactory
// 这里首先构建了一个 RequestBuilder,之后通过遍历 ParamterHandler 列表并调用其 apply 方法将参数应用到 RequestBuilder 中。
okhttp3.Request create(Object[] args) throws IOException {
@SuppressWarnings("unchecked") // It is an error to invoke a method with the wrong arg types.
ParameterHandler<Object>[] handlers = (ParameterHandler<Object>[]) parameterHandlers;

int argumentCount = args.length;
if (argumentCount != handlers.length) {
throw new IllegalArgumentException("Argument count (" + argumentCount
+ ") doesn't match expected count (" + handlers.length + ")");
}

RequestBuilder requestBuilder = new RequestBuilder(httpMethod, baseUrl, relativeUrl,
headers, contentType, hasBody, isFormEncoded, isMultipart);

if (isKotlinSuspendFunction) {
// The Continuation is the last parameter and the handlers array contains null at that index.
argumentCount--;
}

List<Object> argumentList = new ArrayList<>(argumentCount);
for (int p = 0; p < argumentCount; p++) {
argumentList.add(args[p]);
handlers[p].apply(requestBuilder, args[p]);
}

return requestBuilder.get()
.tag(Invocation.class, new Invocation(method, argumentList))
.build();
}

接着看 parseResponse 是如何对 Response 进行解析的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// class:OkHttpCall<T>
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
ResponseBody rawBody = rawResponse.body();

// Remove the body's source (the only stateful object) so we can pass the response along.
rawResponse = rawResponse.newBuilder()
.body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
.build();

// ...

ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody);
try {
// 通过 Converter.convert 方法将 Response 的 body 转换为我们所需要的类型。
T body = responseConverter.convert(catchingBody);
return Response.success(body, rawResponse);
} catch (RuntimeException e) {
// If the underlying source threw an exception, propagate that rather than indicating it was
// a runtime exception.
catchingBody.throwIfCaught();
throw e;
}
}

总结

Retrofit 的注解是一种运行时注解,它通过动态代理对 Service 对象进行创建,通过反射对注解进行解析,这样虽然会有一定性能的损耗,但性能的损耗却带来了十分易用的 API。用户所写的 Service 接口中,每一个 ServiceMethod都对应了一个接口。

对于 Service 的创建,它是通过动态代理,对每个接口内定义的方法进行了代理,若设置 了validateEagerly则会在创建 Service 接口对象时进行注解的解析以及 ServiceMethod 的创建,否则会在方法调用时再创建对应的 ServiceMethod 对象,在多次调用的情况下,它通过 serviceMethodCache 对已经解析的 ServiceMethod 进行了缓存从而避免了重复解析带来的性能损耗。

这个对象的创建首先会经过 RequestFactory.parseAnnotations 对方法中的注解进行解析:

  • 对于方法的请求方式注解,它会通过 parseHttpMethodAndPath 方法获取注解对应的请求方式以及注解中的 url 等信息并保存起来,在创建请求的时候设置进 RequestBuilder
  • 对于方法的 Headers 注解,它会将 Header 注解解析为 Headers 对象并保存起来,在创建请求的时候设置进 RequestBuilder
  • 对于方法的参数,它会将每个参数根据具体的注解(@Query 等)解析为对应的 ParamterHandler,在创建请求的时候,会通过它的 apply 方法将参数提交到 RequestBuilder 中。

之后,这个对象会通过 HttpServiceMethod.parseAnnotationsServiceMethod 对象进行创建,它在创建的过程中同时进行了接口对应的 CallAdapter 以及 Converter 的创建。

其中,CallAdapter 用于将Call 对象适配为需要的类型 T 对象,也就是对 Call 进行转换。

Converter 则是用于将 F 类型的数据转换为 T,往往是用于对 Response的 body 进行转换。

对于 CallAdapterConverter 都是通过它们对应的工厂类进行创建,创建时会根据工厂列表的顺序从前向后尝试进行创建,也就是说在工厂列表中越靠前的工厂其优先级越大。

同时,Retrofit 还引入了对 Continuation 协程的支持,它会将 ServerMethod 最终包装为一个 suspend 方法从而对协程进行支持。

Retrofit的网络请求的执行依赖于 OkHttp,它首先会通过 RequestFactory 进行 Request 的构造,它的参数通过前面解析的信息得来。之后会将这个 Request 包装为一个 okhttp3.Call,在同步和异步请求时分别调用其对应的 execute 及 enqueue 方法。同时,为了避免okhttp3.Call 的重复创建,它对之前创建的 okhttp3.Call 进行了复用。

链接

参考资料:

GitHub

带你一步步剖析Retrofit 源码解析