Retrofit 核心功能、关键节点
1、Retrofit # create() 动态代理:实现对不同业务的 APIService 聚合统一调用
2、CallAdapterFactory:请求适配工厂,比如,实现 RxJava 的支持 (RxJava2CallAdapter)
3、ConverterFactory:解析工厂,Response 数据解析,转为 JavaBean
4、callFactory:OkHttpClient 就是一个 callFactory的实现类,用于创建 RealCall 对象
执行流程
一、使用
1、创建 Retrofit 对象
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addCallAdapterFactory(RxJava2CallAdapterFactory.create());
.addConverterFactory(GsonConverterFactory.create())
.build();
2、定义API 并获取 API 实例
public interface GitHubService {
@GET("users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
}
GitHubService github = retrofit.create(GitHubService.class);
二、Retrofit执行请求的整个流程
//1) 获取 API 实例
XXXService service = Retrofit.create(XXXService.class);
/* 2) 调用 API 实例的 某个网络请求方法
*
* 此时会触发 Retrofit#create()中动态代理的方法,依次执行以下三行代码
*
* ServiceMethod<Object, Object> serviceMethod = loadServiceMethod(method);
* retrofit2.OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
* return serviceMethod.adapt(okHttpCall);
*/
service.requestXXX(...);
//3)获取 ServiceMethod 对象,包含了请求的方法信息、参数信息、CallAdapter、ResponseAdapter、callFactory等
ServiceMethod<Object, Object> serviceMethod = (ServiceMethod<Object, Object>) loadServiceMethod(method);
//4)创建 OkHttpCall 对象,内部封装了同步/异步请求的实现
retrofit2.OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
/* 5)调用 CallAdapter.adapt(okHttpCall)
*
* 不同的 CallAdapter 会有不同的实现,
* i. RxJava2CallAdapter.adapt()会把网络请求封装成一个 Observable<T> 对象返回。
* 这种方式是为了支持RxJava
*
* ii.DefaultCallAdapterFactory.adapt()会把 Call<T> 返回
* 这种方式是不需要支持RxJava的情况,拿到 Call 后,执行同步call.execute(),异步请求call.enqueue()
*/
serviceMethod.adapt(okHttpCall) -> CallAdapter.adapt()
1、获取 API 实例
public final class Retrofit {
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 {
//如果调用的是Object 的方法,则直接调用,使用代理
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
//如果是 default 方法(Java 8 引入),就调用 default 方法
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
retrofit2.OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.adapt(okHttpCall);
}
});
}
}
关键代码:
ServiceMethod<Object, Object> serviceMethod = (ServiceMethod<Object, Object>) loadServiceMethod(method);
retrofit2.OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.adapt(okHttpCall);
2、获取 ServiceMethod
ServiceMethod 中 包含有各个工厂的实例。
// Retrofit#loadServiceMethod()
ServiceMethod<Object, Object> serviceMethod = (ServiceMethod<Object, Object>) loadServiceMethod(method);
(1) ServiceMethod<T> 把接口方法的调用转为一次 HTTP 调用
一个 ServiceMethod 对象对应于一个 API interface 的一个方法
loadServiceMethod(method) 方法负责加载 ServiceMethod。
ServiceMethod loadServiceMethod(Method method) {
ServiceMethod result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = new ServiceMethod.Builder(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
实现了缓存逻辑,同一个 API 的同一个方法,只会创建一次。
我们每次获取 API 实例都是传入的 class 对象,而 class 对象是进程内单例的,
所以获取到它的同一个方法 Method 实例也是单例的,所以这里的缓存是有效的
final class ServiceMethod<R, T> {
private final okhttp3.Call.Factory callFactory;
private final CallAdapter<R, T> callAdapter;
private final Converter<ResponseBody, R> responseConverter;
private final ParameterHandler<?>[] parameterHandlers;
...
ServiceMethod(Builder<R, T> builder) {
this.callFactory = builder.retrofit.callFactory();
this.callAdapter = builder.callAdapter;
this.responseConverter = builder.responseConverter;
this.parameterHandlers = builder.parameterHandlers;
...
}
}
-
1)okhttp3.Call.Factory callFactory 请求工厂
负责创建 HTTP 请求,HTTP 请求被抽象为了 okhttp3.Call 类,
它表示一个已经准备好,可以随时执行的 HTTP 请求;
OkHttpClient 实现了这个接口。在构造Retrofit 对象时,可以指定 callFactory,如果不指定,将默认设置为一个 okhttp3.OkHttpClient
-
2)CallAdapter<R, T> callAdapter 请求适配器
把 retrofit2.Call 转为 T。(注意和 okhttp3.Call 区分开来,retrofit2.Call 表示的是对一个 Retrofit 方法的调用),
这个过程会发送一个 HTTP 请求,拿到服务器返回的数据(通过 okhttp3.Call 实现),
并把数据转换为声明的 T 类型对象(通过 Converter<F, T> 实现);final class ServiceMethod<R, T> { private CallAdapter<T, R> createCallAdapter() { Type returnType = method.getGenericReturnType(); // 省略检查性代码 ... Annotation[] annotations = method.getAnnotations(); try { 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); } } } public final class Retrofit { /* 这个工厂列表我们可以在构造 Retrofit 对象时进行添加 * Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.github.com/") .addCallAdapterFactory() .build() */ final List<CallAdapter.Factory> callAdapterFactories; public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) { return nextCallAdapter(null, returnType, annotations); } /** * 遍历一个 CallAdapter.Factory 列表,让工厂们提供, * 如果最终没有工厂能(根据 returnType 和 annotations)提供需要的 CallAdapter,那将抛出异常。 */ 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; } } ... throw new IllegalArgumentException(...); } }
-
3)responseConverter 是 Converter<ResponseBody, T> 类型,
负责把服务器返回的数据(JSON、XML、二进制或者其他格式,由 ResponseBody 封装)转化为 T 类型的对象;final class ServiceMethod<R, T> { 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); } } } public final class Retrofit { /* 这个工厂列表我们可以在构造 Retrofit 对象时进行添加 * Retrofit retrofit = new Retrofit.Builder() .addConverterFactory(GsonConverterFactory.create()) .build(); */ final List<Converter.Factory> converterFactories; public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) { return nextResponseBodyConverter(null, type, annotations); } /** * 遍历 Converter.Factory 列表,看看有没有工厂能够提供需要的 responseBodyConverter。 * 工厂列表可以在构造 Retrofit 对象时进行添加。 */ 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) { return (Converter<ResponseBody, T>) converter; } } ... throw new IllegalArgumentException(...); } }
-
4)parameterHandlers 则负责解析 API 定义时每个方法的参数,并在构造 HTTP 请求时设置参数;
i.每个参数都会有一个 ParameterHandler,由 ServiceMethod#parseParameter() 方法负责创建
每个参数的信息解析出来后都会包装成一个 ParameterHandler 对象。ii.ServiceMethod#parseParameter()
其主要内容就是解析每个参数使用的注解类型(诸如 Path,Query,Field 等),
对每种类型进行单独的处理。构造 HTTP 请求时,我们传递的参数都是字符串,
那 Retrofit 是如何把我们传递的各种参数都转化为 String 的呢?
还是由 Retrofit 类提供 converter!Converter.Factory 除了提供上一小节提到的 responseBodyConverter,
还提供 requestBodyConverter 和 stringConverter,API 方法中除了 @Body 和 @Part 类型的参数,
都利用 stringConverter 进行转换,
而 @Body 和 @Part 类型的参数则利用 requestBodyConverter 进行转换。这三种 converter 都是通过“询问”工厂列表进行提供,
而工厂列表我们可以在构造 Retrofit 对象时进行添加。(2)工厂让各个模块得以高度解耦
各个工厂负责不同的功能,而Retrofit 值负责向工厂提供用于决策的信息,例如参数/返回值类型/注解等。
3、创建 retrofit2.OkHttpCall
OkHttpCall内部封装了 同步/异步网络请求
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
OkHttpCall 实现了 retrofit2.Call,我们通常会使用它的 execute() 和 enqueue(Callback callback) 接口。
前者用于同步执行 HTTP 请求,后者用于异步执行。
final class OkHttpCall<T> implements Call<T> {
//1)同步请求
@Override
public Response<T> execute() throws IOException {
okhttp3.Call call;
synchronized (this) {
//【1】创建 okhttp3.Call,包括构造参数;
call = rawCall;
if (call == null) {
try {
call = rawCall = createRawCall();
} catch (IOException | RuntimeException e) {
creationFailure = e;
throw e;
}
}
}
//【2】call.execute() 同步执行网络请求,返回 Response 对象
//【3】解析网络请求返回的数据;
return parseResponse(call.execute());
}
// callFactory 就是 OkHttpClient
private okhttp3.Call createRawCall() throws IOException {
Request request = serviceMethod.toRequest(args);
okhttp3.Call call = serviceMethod.callFactory.newCall(request);
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
//解析网络请求返回的数据
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) {
// ...返回错误
}
if (code == 204 || code == 205) {
return Response.success(null, rawResponse);
}
ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
try {
// 内部调用 responseConverter.convert(body) 把body 转成 T
T body = serviceMethod.toResponse(catchingBody);
return Response.success(body, rawResponse);
} catch (RuntimeException e) {
// ...异常处理
}
}
//2)异步请求
@Override
public void enqueue(final Callback<T> callback) {
...
okhttp3.Call call;
Throwable failure;
synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
//【1】创建 okhttp3.Call,包括构造参数;
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();
}
//【2】调用 okhttp3.Call 的 enqueue() 方法,执行异步请求
call.enqueue(new okhttp3.Callback() {
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
Response<T> response;
try {
//【3】解析响应数据
response = parseResponse(rawResponse);
} catch (Throwable e) {
callFailure(e);
return;
}
try {
callback.onResponse(OkHttpCall.this, response);
} catch (Throwable t) {
t.printStackTrace();
}
}
...
});
}
}
4、CallAdapter.adapt(okHttpCall) //请求适配器适配
serviceMethod.adapt(okHttpCall);
内部调用的是 CallAdapter.adapt(call) 方法
final class ServiceMethod<R, T> {
T adapt(Call<R> call) {
return callAdapter.adapt(call);
}
}
CallAdapter#adapt(Call call) 函数负责把 retrofit2.Call 转为 T。
这里 T 当然可以就是 retrofit2.Call,这时我们直接返回参数就可以了,
实际上这正是 DefaultCallAdapterFactory 创建的 CallAdapter 的行为。
至于其他类型的工厂返回的 CallAdapter 的行为,这里暂且不表,后面再单独分析。
三、retrofit-adapters 模块
Retrofit中 CallAdapter 的适配器模式
retrofit 模块内置了 DefaultCallAdapterFactory 和 ExecutorCallAdapterFactory,
它们都适用于 API 方法得到的类型为 retrofit2.Call 的情形,
-
1)DefaultCallAdapterFactory 生产的 adapter 啥也不做,直接把参数返回,
-
2)ExecutorCallAdapterFactory 生产的 adapter 则会在异步调用时在指定的 Executor 上执行回调。
异步请求结束后,会在 callbackExecutor 回调结果
ExecutorCallAdapterFactory(Executor callbackExecutor) -
3)RxJavaCallAdapterFactory
RxJava2CallAdapterFactory#get 方法中对返回值的类型进行了检查,
只支持 rx.Single,rx.Flowable,rx.Maybe,rx.Completable 和 rx.Observable,
然后返回 RxJava2CallAdapter 对象。如果 Retrofit 中设置了 RxJavaCallAdapterFactory,那么 Retrofit的 CallAdapter 就是 RxJava2CallAdapter
RxJava2CallAdapter.adapt() 会返回一个 Obserable对象。
Observable.subscribe,触发 API 调用的执行;final class RxJava2CallAdapter<R> implements CallAdapter<R, Object> { @Override public Object adapt(Call<R> call) { Observable<Response<R>> responseObservable = isAsync //异步请求,创建 CallEnqueueObservable ? new CallEnqueueObservable<>(call) //同步请求,创建 CallExecuteObservable : new CallExecuteObservable<>(call); Observable<?> observable; if (isResult) { observable = new ResultObservable<>(responseObservable); } else if (isBody) { observable = new BodyObservable<>(responseObservable); } else { observable = responseObservable; } if (scheduler != null) { observable = observable.subscribeOn(scheduler); } if (isFlowable) { return observable.toFlowable(BackpressureStrategy.LATEST); } if (isSingle) { return observable.singleOrError(); } if (isMaybe) { return observable.singleElement(); } if (isCompletable) { return observable.ignoreElements(); } return observable; } }
执行网络请求时,会调用 ServiceMethod.adapt() -> RxJava2CallAdapter.adapt()
i.异步请求 CallEnqueueObservable
final class CallEnqueueObservable<T> extends Observable<Response<T>> {
private final Call<T> originalCall;
CallEnqueueObservable(Call<T> originalCall) {
this.originalCall = originalCall;
}
@Override
protected void subscribeActual(Observer<? super Response<T>> observer) {
// Since Call is a one-shot type, clone it for each new observer.
Call<T> call = originalCall.clone();
CallCallback<T> callback = new CallCallback<>(call, observer);
/*
* observer在 callback构造函数中已经把 observer传入,并且在 callback的对应函数中做了回调
* 调用observer#onSubscribe(@NonNull Disposable d)方法,通知应用层要开始请求了
*/
observer.onSubscribe(callback);
call.enqueue(callback);
}
private static final class CallCallback<T> implements Disposable, Callback<T> {
private final Call<?> call;
private final Observer<? super Response<T>> observer;
private volatile boolean disposed;
boolean terminated = false;
CallCallback(Call<?> call, Observer<? super Response<T>> observer) {
this.call = call;
this.observer = observer;
}
@Override
public void onResponse(Call<T> call, Response<T> response) {
...
observer.onNext(response);
...
observer.onComplete();
...
observer.onError(t);
}
@Override
public void onFailure(Call<T> call, Throwable t) {
...
observer.onError(t);
...
}
...
}
}
ii.同步请求 CallExecuteObservable
final class CallExecuteObservable<T> extends Observable<Response<T>> {
private final Call<T> originalCall;
CallExecuteObservable(Call<T> originalCall) {
this.originalCall = originalCall;
}
@Override
protected void subscribeActual(Observer<? super Response<T>> observer) {
// Since Call is a one-shot type, clone it for each new observer.
Call<T> call = originalCall.clone();
CallDisposable disposable = new CallDisposable(call);
observer.onSubscribe(disposable);
boolean terminated = false;
try {
//调用 retrofit.OkHttpCall.execute()会调用 OkHttp.Call.execute()执行同步请求
Response<T> response = call.execute();
if (!disposable.isDisposed()) {
observer.onNext(response);
}
if (!disposable.isDisposed()) {
terminated = true;
observer.onComplete();
}
} catch (Throwable t) {
Exceptions.throwIfFatal(t);
if (terminated) {
RxJavaPlugins.onError(t);
} else if (!disposable.isDisposed()) {
try {
observer.onError(t);
} catch (Throwable inner) {
Exceptions.throwIfFatal(inner);
RxJavaPlugins.onError(new CompositeException(t, inner));
}
}
}
}
private static final class CallDisposable implements Disposable {
private final Call<?> call;
private volatile boolean disposed;
CallDisposable(Call<?> call) {
this.call = call;
}
@Override public void dispose() {
disposed = true;
call.cancel();
}
@Override public boolean isDisposed() {
return disposed;
}
}
}
四、retrofit-converters 模块
GsonConverterFactory 把网络请求返回的 Response 转成 T 对象
public final class GsonConverterFactory extends Converter.Factory {
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonResponseBodyConverter<>(gson, adapter);
}
}
final class GsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
private final Gson gson;
private final TypeAdapter<T> adapter;
GsonResponseBodyConverter(Gson gson, TypeAdapter<T> adapter) {
this.gson = gson;
this.adapter = adapter;
}
@Override
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中 ConverterFactory、CallAdapterFactory 的理解
工厂模式,方便使用者根据需要自定义实现对应功能
六、Gson解析异常数据处理
public class JsonUtil {
public static Gson getGson() {
return new GsonBuilder()
.serializeNulls()
.registerTypeAdapterFactory(new NullTypeToEmptyAdapterFactory())
.create();
}
}
Retrofit创建时调用:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addCallAdapterFactory(RxJava2CallAdapterFactory.create());
.addConverterFactory(GsonConverterFactory.create(JsonUtil.getGson()))
.build();
/**
* Json数据适配器
*/
public class NullTypeToEmptyAdapterFactory implements TypeAdapterFactory {
@Override
public <T> TypeAdapter<T> create (Gson gson, TypeToken<T> type) {
Class<T> rawType = (Class<T>) type.getRawType();
if (rawType == String.class) {
return (TypeAdapter<T>) new StringNullAdapter();
} else if (rawType == Integer.class) {
return (TypeAdapter<T>) new IntegerNullAdapter();
} else if (rawType == Double.class) {
return (TypeAdapter<T>) new DoubleNullAdapter();
} else if (rawType == Float.class) {
return (TypeAdapter<T>) new FloatNullAdapter();
} else if (rawType == Long.class) {
return (TypeAdapter<T>) new LongNullAdapter();
}
return null;
}
class StringNullAdapter extends TypeAdapter<String> {
@Override
public String read (JsonReader reader) throws IOException {
String str = "";
if (reader.peek() == JsonToken.NULL) {
reader.nextNull();
return str;
}
try {
str = reader.nextString();
} catch (Exception e) {
str = JsonUtil.getGson().toJson(new JsonParser().parse(reader));
}
return str;
}
@Override
public void write (JsonWriter writer, String value) throws IOException {
// if (value == null) {
// writer.nullValue();
// return;
// }
writer.value(value);
}
}
class IntegerNullAdapter extends TypeAdapter<Integer> {
@Override
public void write (JsonWriter out, Integer value) throws IOException {
out.value(value);
}
@Override
public Integer read (JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return 0;
}
return in.nextInt();
}
}
class DoubleNullAdapter extends TypeAdapter<Double> {
@Override
public void write (JsonWriter out, Double value) throws IOException {
out.value(value);
}
@Override
public Double read (JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return 0.0;
}
return in.nextDouble();
}
}
class LongNullAdapter extends TypeAdapter<Long> {
@Override
public void write (JsonWriter out, Long value) throws IOException {
out.value(value);
}
@Override
public Long read (JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return 0L;
}
return in.nextLong();
}
}
class FloatNullAdapter extends TypeAdapter<Float> {
@Override
public void write (JsonWriter out, Float value) throws IOException {
out.value(value);
}
@Override
public Float read (JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return 0f;
}
return Float.parseFloat(String.valueOf(in.nextDouble()));
}
}
}
推荐阅读:
拆轮子系列:拆Retrofit https://blog.piasy.com/2016/06/25/Understand-Retrofit/index.html