Retrofit源码学习随笔

Retrofit是什么?

简介

Retrofit,中文的翻译为“式样翻新”的意思,是一个基于OKHttp的RESTful网络请求框架。通俗一点来说,Retrofit就是一个网络请求框架的封装。同样是由Square公司开源的Android热门网络框架之一,其具有功能强大、简洁易用及高可拓展性特点。

官网网址:Retrofit官网

Github地址:Github

特点

1、基于OkHttp并遵循Restful API设计风格

2、通过注解的形式,可简便的配置网络请求参数

3、支持同步及异步的网络请求方式

4、支持RxJava

5、支持多种数据格式的解析(Json、XML、Protobuf等)

Retrofit怎么用?

1、gradle引入库

1
2
3
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0' //配置使用Gson解析响应数据 可选
implementation 'com.squareup.retrofit2:adapter-rxjava:2.4.0' //配置支持RxJava 可选

2、初始化Retrofit对象

1
2
3
4
5
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL) //配置baseUrl
.addConverterFactory(GsonConverterFactory.create()) //配置使用Gson解析响应数据
.addCallAdapterFactory(RxJavaCallAdapterFactory.create()) //配置支持RxJava
.build();

网络接口定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public interface WeatherService {
//使用GET请求 直接返回原始数据
@GET("weather?location=%E5%98%89%E5%85%B4&output=json&ak=5slgyqGDENN7Sy7pw29IUvrZ")
Call<ResponseBody> cityNameQueryWeather();

//使用GET请求 返回Json映射对象
@GET("{weather}?location=%E5%98%89%E5%85%B4&output=json")
Call<WeatherResp> cityWeatherPath(@Path("weather") String weather, @Query("ak") String ak);

//使用POST请求 支持RxJava返回
@FormUrlEncoded()
@POST("{weather}")
rx.Observable<WeatherResp> cityWeatherPost(@Path("weather") String weather, @Field("ak") String ak, @Field("location") String location, @Field("output") String output);

}

同步请求

1
2
3
4
5
6
7
8
9
WeatherService weatherService = retrofit.create(WeatherService.class);
Call<ResponseBody> responseBodyCall = weatherService.cityNameQueryWeather();
try {
Response<ResponseBody> responseBody = responseBodyCall.execute();
System.out.println("call:" + responseBody.body().string());

} catch (IOException e) {
e.printStackTrace();
}

异步请求

1
2
3
4
5
6
7
8
9
10
11
12
13
WeatherService weatherService = retrofit.create(WeatherService.class);
Call<WeatherResp> responseBodyCall = weatherService.cityWeatherPath("weather", "5slgyqGDENN7Sy7pw29IUvrZ");
responseBodyCall.enqueue(new Callback<WeatherResp>() {
@Override
public void onResponse(Call<WeatherResp> call, Response<WeatherResp> response) {
System.out.println("call:" + response.toString());
}

@Override
public void onFailure(Call<WeatherResp> call, Throwable t) {

}
});

RxJava支持

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
WeatherService weatherService = retrofit.create(WeatherService.class);
weatherService.rxCityWeatherPost("weather", "5slgyqGDENN7Sy7pw29IUvrZ", "%E5%98%89%E5%85%B4", "json")
.subscribeOn(Schedulers.io()) //在新线程里面处理网络请求
.observeOn(AndroidSchedulers.mainThread()) //在主线程里面接受返回的数据
.subscribe(new rx.Observer<WeatherResp>() {
@Override
public void onCompleted() {

}

@Override
public void onError(Throwable e) {

}

@Override
public void onNext(WeatherResp weatherResp) {
System.out.println("call:" + weatherResp.toString());
}
});

详细的Retrofit的注解配置及各注解的使用,推荐参考

这是一份很详细的 Retrofit 2.0 使用教程(含实例讲解)

Retrofit核心执行流程是怎样?

关键类功能说明

功能说明
Retrofit 里面包含了很多对象,serviceMethodCache(自定义的接口映射对象集合)、baseUrl(请求地址)、callFactory(默认为OKHttpCall)、converterFactories(数据解析器工厂集合)、callAdapterFactories(Call适配器工厂集合)、callbackExecutor(回调执行,Android平台默认为MainThreadExecutor)使用Builder模型构建
Platform Retrofit中用来管理多平台的方法,支持Android、Java8。通过findPlatform获取对应的平台,同时也初始化了defaultCallAdapterFactory工厂
ServiceMethod 接口映射的网络请求对象,通过动态代理,将自定义接口的标注转换为该对象,将标注及参数生成OkHttp所需的Request对象。Retrofit的create通过动态代理拦截,将每一个自定义接口转换成为一个ServiceMethod对象,并通过通过serviceMethodCache进行缓存。
Call Retrofit定义的网络请求接口,包含execute、enqueue等方法
OkHttpCall Ohttp的Call实现,通过createRawCall得到真正的 okhttp3.Call对象,用于进行实际的网络请求
CallAdapter.Factory CallAdapter的静态工厂,包含get的抽象方法,用于生产CallAdapter对象
ExecutorCallAdapterFactory Android平台默认的CallAdapter工厂,get方法使用匿名内部类实现CallAdapter,返回ExecutorCallbackCall,实现了Call
ExecutorCallbackCall 采用静态代理设计,delegate实际为OkHttpCall,使用callbackExecutor实现回调在主线程中执行
RxJavaCallAdapterFactory Rxjava平台的CallAdapter工厂,get方法返回RxJavaCallAdapter对象
RxJavaCallAdapter Rxjava平台的设配器,返回observable对象
Converter.Factory 数据解析器工厂,用于生产Converter实例
GsonConverterFactory 数据解析工厂实例,返回了GsonResponseBodyConverter数据解析器
GsonResponseBodyConverter Gson的数据解析器,将服务端返回的json对象转换成对应的java模型
Response Retrofit网络请求响应的Response

代码执行流程

image

  1. 通过Build模式构建Retrofit对象
  2. 自定义的接口interface,包含接口方法及相关标注
  3. 执行定义的接口方法
  4. 通过Proxy.newProxyInstance进行动态代理拦截
  5. 通过反射将定义的标注方法解析生成ServiceMethod对象(表示一个网络请求的封装对象)并加入serviceMethodCache队列中,避免重复解析
  6. 创建OkHttpCall对象, 继承了Call接口,桥接okhttp3.Call rawCall
  7. 从Retrofit对象的callAdapterFactories工厂集合获取CallAdapter,并调用adapt方法。如果是默认的使用ExecutorCallAdapterFactory设配返回Call,如果设置了RxJavaCallAdapterFactory,返回observable。
  8. 获取适配器转换后的对象,执行同步请求或者异步请求。
  9. 创建Okhttp的RealCall对象
  10. 通过反射的arg参数,调用serviceMethod.toCall(),构建生成Okhttp的RealCall所需要的Request对象
  11. 通过OkHttp的RealCall执行对应的同步或异步请求
  12. 请求成功,通过parseResponse解析请求参数
  13. 通过数据转换器responseConverter.convert(body),将原始数据转换为对象
  14. 回调解析完的数据对象Respone(T)

Retrofit 如何将定义的interface转换成网络请求?

我们都知道,Retrofit通过自定义interface及相关的标注来描述一个http的请求,使用非常简便,且易于维护。

这是Retrofit设计的精髓之一,,当调用Retrofit的create()方法时,会进行动态代理监听。当执行具体的接口方法时,会回调InvocationHandler。通过反射解析method的标注及参数,生成ServiceMethod对象,ServiceMethod中封装了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
public <T> T create(final Class<T> service) {
Utils.validateServiceInterface(service);
if (validateEagerly) {
eagerlyValidateMethods(service);
}
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();

@Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
throws Throwable {
// If the method is a method from Object then defer to normal invocation.
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
//生成ServiceMethod
ServiceMethod<Object, Object> serviceMethod =o
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.adapt(okHttpCall);
}
});
}

通过源码我们知道,具体的转换方法为 (ServiceMethod<Object, Object>) loadServiceMethod(method),具体的实现如下:

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 = new ServiceMethod.Builder<>(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}

通过Builder构建模式,创建一个ServiceMethod对象,并加入缓存,具体的构造实现如下:

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
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
this.methodAnnotations = method.getAnnotations();
this.parameterTypes = method.getGenericParameterTypes();
this.parameterAnnotationsArray = method.getParameterAnnotations();
}

public ServiceMethod build() {
callAdapter = createCallAdapter();
responseType = callAdapter.responseType();
if (responseType == Response.class || responseType == okhttp3.Response.class) {
throw methodError("'"
+ Utils.getRawType(responseType).getName()
+ "' is not a valid response body type. Did you mean ResponseBody?");
}
responseConverter = createResponseConverter();

for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}

if (httpMethod == null) {
throw methodError("HTTP method annotation is required (e.g., @GET, @POST, etc.).");
}

if (!hasBody) {
if (isMultipart) {
throw methodError(
"Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
}
if (isFormEncoded) {
throw methodError("FormUrlEncoded can only be specified on HTTP methods with "
+ "request body (e.g., @POST).");
}
}

int parameterCount = parameterAnnotationsArray.length;
parameterHandlers = new ParameterHandler<?>[parameterCount];
for (int p = 0; p < parameterCount; p++) {
Type parameterType = parameterTypes[p];
if (Utils.hasUnresolvableType(parameterType)) {
throw parameterError(p, "Parameter type must not include a type variable or wildcard: %s",
parameterType);
}

Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
if (parameterAnnotations == null) {
throw parameterError(p, "No Retrofit annotation found.");
}

parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
}

if (relativeUrl == null && !gotUrl) {
throw methodError("Missing either @%s URL or @Url parameter.", httpMethod);
}
if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
throw methodError("Non-body HTTP method cannot contain @Body.");
}
if (isFormEncoded && !gotField) {
throw methodError("Form-encoded method must contain at least one @Field.");
}
if (isMultipart && !gotPart) {
throw methodError("Multipart method must contain at least one @Part.");
}

return new ServiceMethod<>(this);
}

build()方法会通过反射去解析method的标注、参数的类型等。详细的解析可参考源码ParameterHandler相关实现,这里主要对流程进行剖析。

总结一下,Retrofit通过自定义interface及相关的标注来描述一个http的请求,当调用Retrofit的create()方法时,会进行动态代理监听。当执行具体的接口方法时,会回调InvocationHandler。通过反射解析method的标注及参数,生成ServiceMethod对象,ServiceMethod中封装了OKHttp网络请求所需的相关参数。这就是Retrofit将定义的interface转换成网络请求对象的过程。

Retrofit的Converter机制是如何实现?

Converter种类

Retrofit支持多种数据解析方式,使用时需要在Gradle添加依赖。

数据解析器 Gradle依赖
Gson com.squareup.retrofit2:converter-gson:2.4.0
Jackson com.squareup.retrofit2:converter-jackson:2.4.0
Simple XML com.squareup.retrofit2:converter-simplexml:2.4.0
Protobuf com.squareup.retrofit2:converter-protobuf:2.4.0
Moshi com.squareup.retrofit2:converter-moshi:2.4.0
Wire com.squareup.retrofit2:converter-wire:2.4.0
Scalars com.squareup.retrofit2:converter-scalars:2.4.0

Converter实现流程

添加Converter工厂

首先在Retrofit的初始化添加Converter,addConverterFactory(GsonConverterFactory.create())。具体实现如下:

1
2
3
4
public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}

将Converter的工厂加入到converterFactories集合中。

触发数据转换

通过上述的流程分析,我们知道Retrofit当网络请求成功后会执行,OkHttpCall中的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
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);
}

ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
try {
T body = serviceMethod.toResponse(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;
}
}

其中关键的代码为 T body = serviceMethod.toResponse(catchingBody),具体实现如下:

1
2
3
4
/** Builds a method return value from an HTTP response body. */
R toResponse(ResponseBody body) throws IOException {
return responseConverter.convert(body);
}

数据转换器的创建

这里就是 Converter实现转换的地方,那么responseConverter在哪里进行初始化呢?在ServiceMethod的Build方法中,会调用createResponseConverter()进行数据解析器的创建,实现如下:

1
2
3
4
5
6
7
8
private Converter<ResponseBody, T> createResponseConverter() {
Annotation[] annotations = method.getAnnotations();
try {
return retrofit.responseBodyConverter(responseType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(e, "Unable to create converter for %s", responseType);
}
}

调用了 retrofit.responseBodyConverter方法

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

调用了 retrofit.nextResponseBodyConverter方法

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
public <T> Converter<ResponseBody, T> nextResponseBodyConverter(
@Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
checkNotNull(type, "type == null");
checkNotNull(annotations, "annotations == null");

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

StringBuilder builder = new StringBuilder("Could not locate ResponseBody converter for ")
.append(type)
.append(".\n");
if (skipPast != null) {
builder.append(" Skipped:");
for (int i = 0; i < start; i++) {
builder.append("\n * ").append(converterFactories.get(i).getClass().getName());
}
builder.append('\n');
}
builder.append(" Tried:");
for (int i = start, count = converterFactories.size(); i < count; i++) {
builder.append("\n * ").append(converterFactories.get(i).getClass().getName());
}
throw new IllegalArgumentException(builder.toString());
}

通过Retrofit的converterFactories工厂集合匹配获取开始添加的数据转换工厂

默认的数据转换工厂

通过Retrofit build() 中发现如下代码,converterFactories.add(new BuiltInConverters()),可知Retrofit默认的数据转换器工厂为BuiltInConverters。主要实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
if (type == ResponseBody.class) {
return Utils.isAnnotationPresent(annotations, Streaming.class)
? StreamingResponseBodyConverter.INSTANCE
: BufferingResponseBodyConverter.INSTANCE;
}
if (type == Void.class) {
return VoidResponseBodyConverter.INSTANCE;
}
return null;
}

会将数据转换为ResponseBody对象,所以如果Retrofit默认不使用任何数据解析器,定义interface方法时接收数据对象使用 Call

Retrofit的CallAdapter机制是如何实现?

Retrofit支持多种网络请求适配器方式:guava、Java8和rxjava 。Android默认的适配器工厂为ExecutorCallAdapterFactory,最后的回调通过ExecutorCallbackCall切换至主线程运行。

CallAdapter种类

网络请求适配器 Gradle依赖
guava com.squareup.retrofit2:adapter-guava:2.4.0
Java8 com.squareup.retrofit2:adapter-java8:2.4.0
rxjava com.squareup.retrofit2:adapter-rxjava:2.4.0

CallAdapter实现流程

添加CallAdapter工厂

首先在Retrofit的初始化添加CallAdapter工厂,addCallAdapterFactory(RxJavaCallAdapterFactory.create())。具体实现如下:

1
2
3
4
public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
callAdapterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}

将CallAdapter的工厂加入到callAdapterFactories集合中。

CallAdapter的adapt实现

通过上述Retrofit的create方法中分析可知,当拦截到interface的方法调用后最后会执行 return serviceMethod.adapt(okHttpCall)。adapt的实现如下:

1
2
3
T adapt(Call<R> call) {
return callAdapter.adapt(call);
}

就是在这个地方触发了callAdapter的adapt方法。返回最终适配的具体对象。

默认的CallAdapter工厂

Android平台默认的CallAdapter工厂为ExecutorCallAdapterFactory。通过Retrofit的build()方法可知:

1
2
3
// Make a defensive copy of the adapters and add the default Call adapter.
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

platform.defaultCallAdapterFactory的实现如下:

1
2
3
4
5
6
CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
if (callbackExecutor != null) {
return new ExecutorCallAdapterFactory(callbackExecutor);
}
return DefaultCallAdapterFactory.INSTANCE;
}

ExecutorCallAdapterFactory的CallAdapter创建如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
} else {
final Type responseType = Utils.getCallResponseType(returnType);
return new CallAdapter<Object, Call<?>>() {
public Type responseType() {
return responseType;
}

public Call<Object> adapt(Call<Object> call) {
return new ExecutorCallAdapterFactory.ExecutorCallbackCall(ExecutorCallAdapterFactory.this.callbackExecutor, call);
}
};
}
}

adapt方法最后返回还是Call对象,具体的适配实现由ExecutorCallbackCall执行,具体源码如下:

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

public void enqueue(final Callback<T> callback) {
Utils.checkNotNull(callback, "callback == null");
this.delegate.enqueue(new Callback<T>() {
public void onResponse(Call<T> call, final Response<T> response) {
ExecutorCallbackCall.this.callbackExecutor.execute(new Runnable() {
public void run() {
if (ExecutorCallbackCall.this.delegate.isCanceled()) {
callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
} else {
callback.onResponse(ExecutorCallbackCall.this, response);
}

}
});
}

public void onFailure(Call<T> call, final Throwable t) {
ExecutorCallbackCall.this.callbackExecutor.execute(new Runnable() {
public void run() {
callback.onFailure(ExecutorCallbackCall.this, t);
}
});
}
});
}



public Response<T> execute() throws IOException {
return this.delegate.execute();
}
}

具体的执行还是通过delegate(OkHttpCall)来执行,但是在回调使用了 ExecutorCallbackCall.this.callbackExecutor.execute()方法,Android平台的callbackExecutor实现为MainThreadExecutor。具体源码如下:

1
2
3
4
5
6
7
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());

@Override public void execute(Runnable r) {
handler.post(r);
}
}

所以ExecutorCallAdapterFactory中适配最后的设配对象还是Call,实现还是OkHttpCall,通过 MainThreadExecutor,将回调切换在UI线程中运行

CallAdapter的创建

在ServiceMethod的Build方法中,createCallAdapter()进行适配器的的创建,实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private CallAdapter<T, R> createCallAdapter() {
Type returnType = method.getGenericReturnType();
if (Utils.hasUnresolvableType(returnType)) {
throw methodError(
"Method return type must not include a type variable or wildcard: %s", returnType);
}
if (returnType == void.class) {
throw methodError("Service methods cannot return void.");
}
Annotation[] annotations = method.getAnnotations();
try {
//noinspection unchecked
return (CallAdapter<T, R>) retrofit.callAdapter(returnType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(e, "Unable to create call adapter for %s", returnType);
}
}

调用了 retrofit.callAdapter

1
2
3
 public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}

调用了 retrofit.nextCallAdapter

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
public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
checkNotNull(returnType, "returnType == null");
checkNotNull(annotations, "annotations == null");

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

StringBuilder builder = new StringBuilder("Could not locate call adapter for ")
.append(returnType)
.append(".\n");
if (skipPast != null) {
builder.append(" Skipped:");
for (int i = 0; i < start; i++) {
builder.append("\n * ").append(callAdapterFactories.get(i).getClass().getName());
}
builder.append('\n');
}
builder.append(" Tried:");
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
builder.append("\n * ").append(callAdapterFactories.get(i).getClass().getName());
}
throw new IllegalArgumentException(builder.toString());
}

通过Retrofit的callAdapterFactories工厂集合匹配获取开始添加的适配器工厂

如何自定义一个Converter及CallAdapter?

自定义Converter

1、需要定义一个工厂类继承Converter.Factory

2、复写responseBodyConverter及requestBodyConverter方法

3、在Retrofit定义时加入自定义的Converter,addConverterFactory(new CustomConverterFactory())

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
/**
* @author allen
* @date 2018/8/7
* 返回服务端返回的string结果
*/
public class CustomConverterFactory extends Converter.Factory {

@Nullable
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
return StringResponseBodyConverter.INSTANCE;
}
@Nullable
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
return StringRequestBodyConverter.INSTANCE;
}

static final class StringResponseBodyConverter implements Converter<ResponseBody, String> {
static final CustomConverterFactory.StringResponseBodyConverter INSTANCE = new CustomConverterFactory.StringResponseBodyConverter();

@Override
public String convert(ResponseBody value) {

try {
System.out.println("CustomConverterFactory");
return value.string();
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
}
static final class StringRequestBodyConverter implements Converter<RequestBody, RequestBody> {
static final CustomConverterFactory.StringRequestBodyConverter INSTANCE = new CustomConverterFactory.StringRequestBodyConverter();

@Override
public RequestBody convert(@NonNull RequestBody value) {
return value;
}
}
}

自定义CallAdapter

1、需要定义一个工厂类继承CallAdapter.Factory

2、复写CallAdapter<?, ?> get方法

3、在Retrofit定义时加入自定义的CallAdapter, addCallAdapterFactory(new CustomCallAdapterFactory())

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* @author allen
* @date 2018/8/7
*/
public class CustomCallAdapterFactory extends CallAdapter.Factory {
@Nullable
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {

return new CallAdapter<Object, Object>() {
@Override
public Type responseType() {
return String.class;
}

@Override
public Object adapt(Call<Object> call) {
System.out.println("CustomCallAdapterFactory adapt(");
return call;
}
};
}
}

Retrofit中运用了那些设计模式?

1、建造者模式

Retrofit对象的创建、ServiceMethod对象创建都使用Build模式,将复杂对象的创建和表示分离,调用者不需要知道复杂的创建过程,使用Build的相关方法进行配置创建对象。

2、外观模式

Retrofit对外提供了统一的调度,屏蔽了内部的实现,使得使用该网络库简单便捷。

3、动态代理模式

通过动态代理的方式,当调用Retrofit的create()方法时,会进行动态代理监听。当执行具体的接口方法时,会回调InvocationHandler。通过反射解析method的标注及参数,生成ServiceMethod对象。

4、静态代理模式
Android平台默认的适配器ExecutorCallbackCall,采用静态代理的模式。具体的实现delegate为OkHttpCall。

5、工厂模式
Converter及CallAdapter的创建都采用了工厂模式进行创建。

6、适配器模式
CallAdapter的adapt采用了适配器模式,使得interface的返回对象可以动态扩展,增强了灵活性

总结

思考

大多数流行的开源框架都是经过顶级coder的设计,包含了很多精妙的设计。多学习分析,收益良多。

参考资料

这是一份很详细的 Retrofit 2.0 使用教程(含实例讲解)

Android:手把手带你深入剖析 Retrofit 2.0 源码