目前比较流行的使用Retrofit的方法是Retrofit + RxJava + Gson
, 之前的Retrofit学习(二)已经分析过Retrofit是如何结合RxJava,这一篇主要看一下同Gson的结合
要想在Retrofit中使用Gson, 需要添加Gson对应的Converter:
OkHttpclient client = new OkHttpClient.Builder().build();
Retrofit retrofit = new Retrofit.Builder()
.client(client)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
//添加Gson
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("http://localhost:4567/")
.build();
GsonConverterFactory
public final class GsonConverterFactory extends Converter.Factory {
public static GsonConverterFactory create() {
return create(new Gson());
}
public static GsonConverterFactory create(Gson gson) {
return new GsonConverterFactory(gson);
}
private final Gson gson;
private GsonConverterFactory(Gson gson) {
if (gson == null) throw new NullPointerException("gson == null");
this.gson = gson;
}
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonResponseBodyConverter<>(gson, adapter);
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonRequestBodyConverter<>(gson, adapter);
}
}
从之前的Retrofit学习(一)中我们可以知道,每次调用接口方法时都会通过ServiceMethod.Builder.build()
创建一个ServiceMethod
对象, ServiceMethod.Builder.build()
会初始化responseConverter
, 经过一系列调用最终会调用Converter.Factory.responseBodyConverter
,如果在初始化Retrofit时添加了GsonConverterFactory
,则会相应地调用GsonConverterFactory.responseBodyConverter
GsonConverterFactory.responseBodyConverter
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonResponseBodyConverter<>(gson, adapter);
}
从之前的Retrofit学习(一)和Retrofit学习(二)可以知道,最终的步骤都会是OkHttpCall.execute
或OkHttpCall.enqueue
,不论是enqueue
还是execute
,都会调用OkHttpCall.parseResponse
方法,该方法最主要的作用是从okhttp3.Response
中得到okhttp3.ResponseBody
,之后调用ServiceMethod.toResponse
ServiceMethod.toResponse
R toResponse(ResponseBody body) throws IOException {
return responseConverter.convert(body);
}
调用Converter.convert
转换结果,这里的Convert
就是GsonResponseBodyConverter
GsonResponseBodyConverter.convert
public T convert(ResponseBody value) throws IOException {
JsonReader jsonReader = gson.newJsonReader(value.charStream());
try {
return adapter.read(jsonReader);
} finally {
value.close();
}
}