Retrofit 源码分析

摘要

通过分析Retrofit源码,了解这款简洁的网络库如何提高我们的工作效率。通过动态代理技术,创建我们接口对象,以提供我们调用接口函数。通过解析接口定义的函数,装配成OkHttp网络请求所需的数据并发起网络请求。我们可以根据自己的需求,自定义请求适配器和响应转换器。

流程分析

动态代理

我们定义了service接口,并通过retrofit对象的create函数创建了service类型的对象。通过该对象,我们可以调用在service接口定义的函数,从而发起定义的网络请求。

1
val service=retrofit.create(service::class.java)

Retrofit通过动态代理技术生成我们定义service接口代理对象,因此调用代理对象的函数时都会转发到InvocationHandler对象的invoke函数。

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
public <T> T create(final Class<T> service) {
validateServiceInterface(service);
return (T)
Proxy.newProxyInstance(
service.getClassLoader(),
new Class<?>[] {service},
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 {
//判断是否Obect的默认方法
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
args = args != null ? args : emptyArgs;
//判断是否特定平台的方法,例如Android
return platform.isDefaultMethod(method)
? platform.invokeDefaultMethod(method, service, proxy, args)
: loadServiceMethod(method).invoke(args);
}
});
}

loadServiceMethod

invoke函数,我们只关心loadServiceMethod(method).invoke(args)函数。loadServiceMethod(method)函数会返回一个ServiceMethod对象,ServiceMethod是一个抽象类,唯一直接实现类是HttpServiceMethod。也就是说这里调用了HttpServiceMethod.invoke(args)

1
2
3
4
5
6
7
8
9
10
11
12
13
ServiceMethod<?> loadServiceMethod(Method method) {
ServiceMethod<?> result = serviceMethodCache.get(method);
if (result != null) return result;

synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = ServiceMethod.parseAnnotations(this, method);
serviceMethodCache.put(method, result);
}
}
return result;
}

loadServiceMethod函数主要先通过缓存serviceMethodCache获取ServiceMethod对象,如果缓存中没有获取到ServiceMethod对象,则通过ServiceMethod.parseAnnotations解析获取ServiceMethod对象,并将其放在缓存中。serviceMethodCache是一个ConcurrentHashMap,以MethodKey,ServiceMethodvalueServiceMethod.parseAnnotations(this, method)主要是解析Method对象(我们定义的方法)的注解,参数及注解以及返回类型,然后通过HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory)生成ServerMethod对象。

ServiceMethod.parseAnnotations

该函数分别调用了RequestFactory类和HttpServiceMethodparseAnnotations函数。RequestFactory类主要封装本次网络请求的大多数信息,例如methodheaders,httpMethod等等。HttpServiceMethodServerMethod的子类,主要用来创建请求适配器和数据转换器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
//解析方法的注解和参数的注解及值
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.");
}

return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}

RequestFactory.parseAnnotations

RequestFactory.parseAnnotations(retrofit, method)通过构建者模式创建RequestFactory对象。构建的过程主要是解析传递进来的参数method对象上相关信息,并赋值到RequestFactory对象相关属性上。Method对象代表着反射上的一个函数,包含这个该函数的相关信息,例如注解,参数,返回类型等。

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
static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
return new Builder(retrofit, method).build();
}

Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
this.methodAnnotations = method.getAnnotations();
this.parameterTypes = method.getGenericParameterTypes();
this.parameterAnnotationsArray = method.getParameterAnnotations();
}

RequestFactory build() {
//1、解析方法上注解
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
......
int parameterCount = parameterAnnotationsArray.length;
parameterHandlers = new ParameterHandler<?>[parameterCount];
for (int p = 0, lastParameter = parameterCount - 1; p < parameterCount; p++) {
//解析函数参数,包括其注解和值
parameterHandlers[p] =
parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p], p == lastParameter);
}
......
return new RequestFactory(this);
}

build函数主要解析方法上的注解,参数注解。 parseMethodAnnotation(annotation)用来解析方法的注解,根据anotation的类型,例如GETPOST等等,然后根据这些方法类型在HTTP报文对应的特性,设置相关属性,例如GET类型的请求没有请求体hasBody=false,POST类型的hasBody=true

通过parseParameter解析函数参数注解和获取对应的值。参数注解的解析和函数注解的解析类似,主要检查我们使用方式是否正确和设置相关属性。并且也会判断当前函数是否Kotlin协程中的挂起函数(后文分析)。

HttpServiceMethod.parseAnnotations

HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory)又是干了什么呢?将上面解析生成的RequestFactory,生成请求适配器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
 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) {//是否支持协程
Type[] parameterTypes = method.getGenericParameterTypes();
Type responseType =
Utils.getParameterLowerBound(
0, (ParameterizedType) parameterTypes[parameterTypes.length - 1]);
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 {
adapterType = method.getGenericReturnType(); //获取方法的返回类型
}
//遍历Retrofit的CallAdapter列表,寻找是否有符合处理该adapterType的CallAdapter
CallAdapter<ResponseT, ReturnT> callAdapter =
createCallAdapter(retrofit, method, adapterType, annotations);
Type responseType = callAdapter.responseType();

......

//遍历Retrofit的转换器列表,寻找合适的转换器
Converter<ResponseBody, ResponseT> responseConverter =
createResponseConverter(retrofit, method, responseType);

okhttp3.Call.Factory callFactory = retrofit.callFactory;
if (!isKotlinSuspendFunction) {
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);//非协程情况下,HtttpServerMethod的子类
} else if (continuationWantsResponse) {
//使用了协程,且返回类型Response
return (HttpServiceMethod<ResponseT, ReturnT>)
new SuspendForResponse<>(
requestFactory,
callFactory,
responseConverter,
(CallAdapter<ResponseT, Call<ResponseT>>) callAdapter);
} else {
//使用了协程,且返回类型ResponseBody
return (HttpServiceMethod<ResponseT, ReturnT>)
new SuspendForBody<>(
requestFactory,
callFactory,
responseConverter,
(CallAdapter<ResponseT, Call<ResponseT>>) callAdapter,
continuationBodyNullable);
}
}

在创建CallAdatperConverter后,根据是否协程,返回不同的HttpServiceMethod子类。

createCallAdapter

其中createCallAdapter(retrofit, method, adapterType, annotations);创建CallAdapted对象。

1
2
3
4
5
6
7
8
9
private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
Retrofit retrofit, Method method, Type returnType, Annotation[] annotations) {
try {
//noinspection unchecked
return (CallAdapter<ResponseT, ReturnT>) retrofit.callAdapter(returnType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(method, e, "Unable to create call adapter for %s", returnType);
}
}

调用retrofit.callAdapter(returnType, annotations),根据返回类型retrunType选择合适的请求适配器。需要注意到的是,这里是从头开始遍历,如果前面适配器符合条件,意味着会被优先选用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}

public CallAdapter<?, ?> nextCallAdapter(
@Nullable CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) {
......
int start = callAdapterFactories.indexOf(skipPast) + 1;
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
......
}

nextCallAdapter函数主要通过循环遍历在构建Retrofit是保存在callAdapterFactories列表的CallAdapter,通过其get函数查看是否匹配。如果Android SDK_INT>=24返回的是CompletableFutureCallAdapterFactory,否则返回的是DefaultCallAdapterFactory

看看CompletableFutureCallAdapterFactory对象的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
@Override
public @Nullable CallAdapter<?, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != CompletableFuture.class) {
return null;
}
if (!(returnType instanceof ParameterizedType)) {
throw new IllegalStateException(
"CompletableFuture return type must be parameterized"
+ " as CompletableFuture<Foo> or CompletableFuture<? extends Foo>");
}
Type innerType = getParameterUpperBound(0, (ParameterizedType) returnType);

if (getRawType(innerType) != Response.class) {
// Generic type is not Response<T>. Use it for body-only adapter.
return new BodyCallAdapter<>(innerType);
}

// Generic type is Response<T>. Extract T and create the Response version of the adapter.
if (!(innerType instanceof ParameterizedType)) {
throw new IllegalStateException(
"Response must be parameterized" + " as Response<Foo> or Response<? extends Foo>");
}
Type responseType = getParameterUpperBound(0, (ParameterizedType) innerType);
return new ResponseCallAdapter<>(responseType);
}

CompletableFutureCallAdapterFactoryget函数根据函数返回类型是否与自己要处理的返回类型一致,不一致则返回null,表示不处理,例如这里是CompletableFuture。然后进一步检查返回值的合法性,例如是不是泛型对象。最终根据泛型对象最外层类型返回CallAdapter的子类BodyCallAdapterResponseCallAdapter。两者的主要区别是其adapt函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
//BodyCallAdapter   
@Override
public CompletableFuture<R> adapt(final Call<R> call) {
CompletableFuture<R> future = new CallCancelCompletableFuture<>(call);
call.enqueue(new BodyCallback(future));
return future;
}
//ResponseCallAdapter
public CompletableFuture<Response<R>> adapt(final Call<R> call) {
CompletableFuture<Response<R>> future = new CallCancelCompletableFuture<>(call);
call.enqueue(new ResponseCallback(future));
return future;
}

loadServiceMethod(method).invoke(args)

回到loadServiceMethod(method).invoke(args),也就是说,这里实际调用了CallAdapter对象的invoke函数。

1
2
3
4
5
@Override
final @Nullable ReturnT invoke(Object[] args) {
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}

invoke函数主要是构建OkHttpCall并调用adapt函数。这里分析ResponseCallAdapteradapt函数。

1
2
3
4
5
6
@Override
public CompletableFuture<Response<R>> adapt(final Call<R> call) {
CompletableFuture<Response<R>> future = new CallCancelCompletableFuture<>(call);
call.enqueue(new ResponseCallback(future));
return future;
}

网络请求

adapt函数调用了OkHttpCallenqueue函数。是不是跟OKHttp的异步请求很相似。

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
@Override
public void enqueue(final Callback<T> callback) {
Objects.requireNonNull(callback, "callback == null");

okhttp3.Call call;
Throwable failure;

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;
}

if (canceled) {
call.cancel();
}

call.enqueue(
new okhttp3.Callback() {
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
Response<T> response;
try {
response = parseResponse(rawResponse);//解析 原始数据,调用转化适配器
} catch (Throwable e) {
throwIfFatal(e);
callFailure(e);
return;
}

try {
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(e);
}

private void callFailure(Throwable e) {
try {
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable t) {
throwIfFatal(t);
t.printStackTrace(); // TODO this is not great
}
}
});
}

通过enqueue函数的简单分析,就是创建OkHttpCall对象,并调用enqueue函数。然后发起网络请求,请求成功之后调用parseResponse解析响应数据。

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
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();

int code = rawResponse.code();
if (code < 200 || code >= 300) {
try {
// Buffer the entire body to avoid future I/O.
ResponseBody bufferedBody = Utils.buffer(rawBody);
return Response.error(bufferedBody, rawResponse);
} finally {
rawBody.close();
}
}

if (code == 204 || code == 205) {
rawBody.close();
return Response.success(null, rawResponse);
}

ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody);
try {
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;
}
}

createResponseConverter

重点地方就是在函数最后的地方调用了T body = responseConverter.convert(catchingBody);将原始数据转化成我们需要的数据类型。在HttpServiceMethodparseAnnotations函数中createResponseConverter创建响应数据转换器。

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
 private static <ResponseT> Converter<ResponseBody, ResponseT> createResponseConverter(
Retrofit retrofit, Method method, Type responseType) {
Annotation[] annotations = method.getAnnotations();
try {
return retrofit.responseBodyConverter(responseType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(method, e, "Unable to create converter for %s", responseType);
}
}

public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
return nextResponseBodyConverter(null, type, annotations);
}

public <T> Converter<ResponseBody, T> nextResponseBodyConverter(
@Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
......
int start = converterFactories.indexOf(skipPast) + 1;
for (int i = start, count = converterFactories.size(); i < count; i++) {
Converter<ResponseBody, ?> converter =
converterFactories.get(i).responseBodyConverter(type, annotations, this);
if (converter != null) {
//noinspection unchecked
return (Converter<ResponseBody, T>) converter;
}
}
......
}

响应转换器与请求适配器的创建过程很相似。在创建Retrofit对象时,会将相关转化器保存到converterFactories列表,通过转化器的responseBodyConverter函数判断是否处理该响应数据。这里看下OptionalConverterFactory

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
final class OptionalConverterFactory extends Converter.Factory {
static final Converter.Factory INSTANCE = new OptionalConverterFactory();

@Override
public @Nullable Converter<ResponseBody, ?> responseBodyConverter(
Type type, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(type) != Optional.class) {
return null;
}

Type innerType = getParameterUpperBound(0, (ParameterizedType) type);
Converter<ResponseBody, Object> delegate =
retrofit.responseBodyConverter(innerType, annotations);
return new OptionalConverter<>(delegate);
}

@IgnoreJRERequirement
static final class OptionalConverter<T> implements Converter<ResponseBody, Optional<T>> {
final Converter<ResponseBody, T> delegate;

OptionalConverter(Converter<ResponseBody, T> delegate) {
this.delegate = delegate;
}

@Override
public Optional<T> convert(ResponseBody value) throws IOException {
return Optional.ofNullable(delegate.convert(value));
}
}
}

responseBodyConverter逻辑很简单,判断放回类型Type是不是Optional.class,然后返回OptionalConverter。那么网络成功返回数据就会调用convert函数,而这个直接委托给下一个转化器。

而在构建converterFactories列表的时候,会优先添加BuiltInConverters,然后是我们自定义的转换器,最后如果Android SDK>=24,才添加OptionalConverterFactory。也就是说从这里可以看到优先权。

而构建callAdapterFactories列表,则是先我们自定义的,再是平台默认的适配器。

通常情况下,我们都会添加GsonConverterFactory适配器,将gson转化成对象类型。

1
2
3
4
5
6
@Override
public Converter<ResponseBody, ?> responseBodyConverter(
Type type, Annotation[] annotations, Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonResponseBodyConverter<>(gson, adapter);
}

GsonResponseBodyConverterconvert函数。

1
2
3
4
5
6
7
8
9
10
11
12
public T convert(ResponseBody value) throws IOException {
JsonReader jsonReader = gson.newJsonReader(value.charStream());
try {
T result = adapter.read(jsonReader);
if (jsonReader.peek() != JsonToken.END_DOCUMENT) {
throw new JsonIOException("JSON document was not fully consumed.");
}
return result;
} finally {
value.close();
}
}

到这里,Retrofit整个源码流程就分析完了。所以也应该学会了如何自定适配器和转换器了。

协程

Retrofit在目前版本2.6.0开始就已经支持协程,即允许在接口中定义挂起函数。那Retrofit如何确定接口定义的函数是挂起函数呢?

在上一节分析RequestFactory.parseAnotations中分析函数注解,说到parseParameter解析函数参数注解,有提到判断函数是否挂起函数。来看是如何判断的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 private @Nullable ParameterHandler<?> parseParameter(
int p, Type parameterType, @Nullable Annotation[] annotations, boolean allowContinuation) {
······
if (result == null) {//参数没有注解
if (allowContinuation) {//参数为函数最后一个参数
try {
if (Utils.getRawType(parameterType) == Continuation.class) {//参数类型为Continuation
isKotlinSuspendFunction = true;
return null;
}
} catch (NoClassDefFoundError ignored) {
}
}
throw parameterError(method, p, "No Retrofit annotation found.");
}

return result;
}

判断是否协程函数有三个条件:

  1. 函数参数没有注解
  2. 该参数是在函数中的最后一个位置
  3. 该参数的类型是Continuation.class

但这跟我们理解中协程的挂起函数区别有点大啊。因为这是我们理解中的Kotlin挂起函数,当它编译后成Java字节码后,会自动在函数最后一个参数增加Continuation类型的参数。

Kotlin函数

1
suspend fun getData()

Java函数

1
void getData(Continuation c)

通过解析接口中函数的最后一个参数没有注解,而且类型为Continuation时,就确定为了一个Kotlin协程挂起函数,并将ReqeustFactoryisKotlinSuspendFunction设置为true

HttpServiceMethod.parseAnnotations解析时根据isKotlinSuspendFunction来走不同的分支,例如isKotlinSuspendFunction=true情况下,返回的是SuspendForResponse,=false情况下,返回的是CallAdapter。看看具体处理了哪些工作。

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
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;
//协程情况下,与非协程情况下类似,获取返回类型adapterType,用于创建CallAdapter
if (isKotlinSuspendFunction) {
Type[] parameterTypes = method.getGenericParameterTypes();
Type responseType =
Utils.getParameterLowerBound(
0, (ParameterizedType) parameterTypes[parameterTypes.length - 1]);
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 {
adapterType = method.getGenericReturnType();//非协程情况
}

CallAdapter<ResponseT, ReturnT> callAdapter =
createCallAdapter(retrofit, method, adapterType, annotations);
Type responseType = callAdapter.responseType();

......

Converter<ResponseBody, ResponseT> responseConverter =
createResponseConverter(retrofit, method, responseType);

okhttp3.Call.Factory callFactory = retrofit.callFactory;
if (!isKotlinSuspendFunction) {//非协程情况
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
} else if (continuationWantsResponse) {
////使用了协程,且返回类型Response
return (HttpServiceMethod<ResponseT, ReturnT>)
new SuspendForResponse<>(
requestFactory,
callFactory,
responseConverter,
(CallAdapter<ResponseT, Call<ResponseT>>) callAdapter);
} else {
////使用了协程,且返回类型ResponseBody
return (HttpServiceMethod<ResponseT, ReturnT>)
new SuspendForBody<>(
requestFactory,
callFactory,
responseConverter,
(CallAdapter<ResponseT, Call<ResponseT>>) callAdapter,
continuationBodyNullable);
}
}

在这里根据接口的函数返回类型的不同,返回SuspendForResponse或者SuspendForBody

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
static final class SuspendForResponse<ResponseT> extends HttpServiceMethod<ResponseT, Object> {
private final CallAdapter<ResponseT, Call<ResponseT>> callAdapter;

SuspendForResponse(
RequestFactory requestFactory,
okhttp3.Call.Factory callFactory,
Converter<ResponseBody, ResponseT> responseConverter,
CallAdapter<ResponseT, Call<ResponseT>> callAdapter) {
super(requestFactory, callFactory, responseConverter);
this.callAdapter = callAdapter;
}

@Override
protected Object adapt(Call<ResponseT> call, Object[] args) {
call = callAdapter.adapt(call);

//noinspection unchecked Checked by reflection inside RequestFactory.
Continuation<Response<ResponseT>> continuation =
(Continuation<Response<ResponseT>>) args[args.length - 1];

// See SuspendForBody for explanation about this try/catch.
try {
return KotlinExtensions.awaitResponse(call, continuation);
} catch (Exception e) {
return KotlinExtensions.suspendAndThrow(e, continuation);
}
}
}

通过调用OkHttpCall扩展函数来实现网络请求。我们知道非协程下是通过创建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
suspend fun <T : Any> Call<T>.await(): T {
return suspendCancellableCoroutine { continuation ->
continuation.invokeOnCancellation {
cancel()
}
enqueue(object : Callback<T> {
override fun onResponse(call: Call<T>, response: Response<T>) {
if (response.isSuccessful) {
val body = response.body()
if (body == null) {
val invocation = call.request().tag(Invocation::class.java)!!
val method = invocation.method()
val e = KotlinNullPointerException("Response from " +
method.declaringClass.name +
'.' +
method.name +
" was null but response body type was declared as non-null")
continuation.resumeWithException(e)
} else {
continuation.resume(body)
}
} else {
continuation.resumeWithException(HttpException(response))
}
}

override fun onFailure(call: Call<T>, t: Throwable) {
continuation.resumeWithException(t)
}
})
}
}

也就是说,非协程与协程下的Retrofit的工作流程差不多。协程情况下,在RequestFactory解析,确定是协程,在HttpserviceMethod解析走不同的路径,通过Call扩展函数实现网络请求。

动态代理

说到动态代理,总是离不开静态代理和代理模式。静态代理总是要写接口,然后代理类和被代理类实现该接口,客户端通过代理类使用接口提供的功能,而代理类把功能实际的工作转到被代理类。问题在哪里,每次我们都懂得去实现代理类和代理类,如果很多个接口,这样会很累的,毕竟程序员都是懒的。再说如果这样,用Retrofit这种第三方库,怎么知道用户创建什么样的接口,怎么去实现他们功能?那就是利用Java的动态代理技术了。动态代理在使用上也可以理解是一套模板。

首先,定义接口,以及实现类,也就是我们对外提供的功能。

1
2
3
4
5
6
7
8
9
10
11
public interface Service {
void coding();
}

public class CoderService implements Service {
@Override
public void coding() {
System.out.println("提供编程服务");

}
}

第二,实现InvocationHandler的子类。核心点在于实现invoke函数,调用接口的函数都会转到这里来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Handler implements InvocationHandler {

private Object service;

public Handler(Object service) {
this.service = service;
}

@Override
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
System.out.println("开发了");
method.invoke(service,objects);
System.out.println("结束了");
return null;
}
}

最后,创建Proxy.newProxyInstance接口对象。在Java中,接口和抽象类是不能被直接实例化的。

1
2
3
4
5
6
7
8
public class Main {
public static void main(String[] args) {
Service service = new CoderService();
InvocationHandler handler = new Handler(service);
Service se = (Service) Proxy.newProxyInstance(Service.class.getClassLoader(), new Class[]{Service.class}, handler);
se.coding();
}
}

这样就可以通过实例化的接口对象,使用相关功能。

Retrofit通过在InvocationHandlerinvoke解析Method来获得网络请求所需要的的数据。

总结

Retrofit通过Java动态代理技术生成我们请求接口的对象,而我们调用对象的任何函数时,其实都转到InvocationHandler对象的invoke函数。而invoke函数的主要工作就是解析我们在接口中定义函数,包括解析注解,参数注解及值,以及返回类型,然后封装到RequestFactory,然后通过HttpServiceMethod.parseAnnotations函数,查找合适的请求适配器和响应转换器,最后将RequestFactory和适配器、转换器封装成HttpServiceMethod的子类,并调用其invoke函数,通过OkHttp发起网络请求。

通过源码分析,我们知道,一个优秀的的框架都会使用缓存,例如这里方法的解析,OkHttp请求的缓存。同时也知道Retrofit目前已经支持协程,即挂起函数。