转载
Retrofit 核心功能、关键节点
1、Retrofit # create() 动态代理:实现对不同业务的 APIService 聚合统一调用
2、CallAdapterFactory:请求适配工厂,比如,实现 RxJava 的支持 (RxJava2CallAdapter)
3、ConverterFactory:解析工厂,Response 数据解析,转为 JavaBean
4、callFactory:OkHttpClient 就是一个 callFactory的实现类,用于创建 RealCall 对象
执行流程
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addCallAdapterFactory(RxJava2CallAdapterFactory.create());
.addConverterFactory(GsonConverterFactory.create())
.build();
public interface GitHubService {
@GET("users/{user}/repos")
Call> listRepos(@Path("user") String user);
}
GitHubService github = retrofit.create(GitHubService.class);
//1) 获取 API 实例
XXXService service = Retrofit.create(XXXService.class);
/* 2) 调用 API 实例的 某个网络请求方法
*
* 此时会触发 Retrofit#create()中动态代理的方法,依次执行以下三行代码
*
* ServiceMethod
public final class Retrofit {
public T create(final Class 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 serviceMethod =
(ServiceMethod) loadServiceMethod(method);
retrofit2.OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.adapt(okHttpCall);
}
});
}
}
关键代码:
ServiceMethod serviceMethod = (ServiceMethod) loadServiceMethod(method);
retrofit2.OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.adapt(okHttpCall);
ServiceMethod 中 包含有各个工厂的实例。
// Retrofit#loadServiceMethod()
ServiceMethod serviceMethod = (ServiceMethod) loadServiceMethod(method);
(1) ServiceMethod
一个 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 {
private final okhttp3.Call.Factory callFactory;
private final CallAdapter callAdapter;
private final Converter responseConverter;
private final ParameterHandler>[] parameterHandlers;
...
ServiceMethod(Builder 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
把 retrofit2.Call 转为 T。
(注意和 okhttp3.Call 区分开来,retrofit2.Call 表示的是对一个 Retrofit 方法的调用),
这个过程会发送一个 HTTP 请求,拿到服务器返回的数据(通过 okhttp3.Call 实现),
并把数据转换为声明的 T 类型对象(通过 Converter
final class ServiceMethod {
private CallAdapter createCallAdapter() {
Type returnType = method.getGenericReturnType();
// 省略检查性代码
...
Annotation[] annotations = method.getAnnotations();
try {
return (CallAdapter) 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 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
负责把服务器返回的数据(JSON、XML、二进制或者其他格式,由 ResponseBody 封装)转化为 T 类型的对象;
final class ServiceMethod {
private Converter 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 converterFactories;
public Converter responseBodyConverter(Type type, Annotation[] annotations) {
return nextResponseBodyConverter(null, type, annotations);
}
/**
* 遍历 Converter.Factory 列表,看看有没有工厂能够提供需要的 responseBodyConverter。
* 工厂列表可以在构造 Retrofit 对象时进行添加。
*/
public Converter 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 converter =
converterFactories.get(i).responseBodyConverter(type, annotations, this);
if (converter != null) {
return (Converter) 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 值负责向工厂提供用于决策的信息,例如参数/返回值类型/注解等。
OkHttpCall内部封装了 同步/异步网络请求
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
OkHttpCall 实现了 retrofit2.Call,我们通常会使用它的 execute() 和 enqueue(Callback callback) 接口。
前者用于同步执行 HTTP 请求,后者用于异步执行。
final class OkHttpCall implements Call {
//1)同步请求
@Override
public Response 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 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 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 response;
try {
//【3】解析响应数据
response = parseResponse(rawResponse);
} catch (Throwable e) {
callFailure(e);
return;
}
try {
callback.onResponse(OkHttpCall.this, response);
} catch (Throwable t) {
t.printStackTrace();
}
}
...
});
}
}
serviceMethod.adapt(okHttpCall);
内部调用的是 CallAdapter.adapt(call) 方法
final class ServiceMethod {
T adapt(Call call) {
return callAdapter.adapt(call);
}
}
CallAdapter#adapt(Call call) 函数负责把 retrofit2.Call 转为 T。
这里 T 当然可以就是 retrofit2.Call,这时我们直接返回参数就可以了,
实际上这正是 DefaultCallAdapterFactory 创建的 CallAdapter 的行为。
至于其他类型的工厂返回的 CallAdapter 的行为,这里暂且不表,后面再单独分析。
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 implements CallAdapter {
@Override
public Object adapt(Call call) {
Observable> 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 extends Observable> {
private final Call originalCall;
CallEnqueueObservable(Call originalCall) {
this.originalCall = originalCall;
}
@Override
protected void subscribeActual(Observer super Response> observer) {
// Since Call is a one-shot type, clone it for each new observer.
Call call = originalCall.clone();
CallCallback 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 implements Disposable, Callback {
private final Call> call;
private final Observer super Response> observer;
private volatile boolean disposed;
boolean terminated = false;
CallCallback(Call> call, Observer super Response> observer) {
this.call = call;
this.observer = observer;
}
@Override
public void onResponse(Call call, Response response) {
...
observer.onNext(response);
...
observer.onComplete();
...
observer.onError(t);
}
@Override
public void onFailure(Call call, Throwable t) {
...
observer.onError(t);
...
}
...
}
}
ii.同步请求 CallExecuteObservable
final class CallExecuteObservable extends Observable> {
private final Call originalCall;
CallExecuteObservable(Call originalCall) {
this.originalCall = originalCall;
}
@Override
protected void subscribeActual(Observer super Response> observer) {
// Since Call is a one-shot type, clone it for each new observer.
Call call = originalCall.clone();
CallDisposable disposable = new CallDisposable(call);
observer.onSubscribe(disposable);
boolean terminated = false;
try {
//调用 retrofit.OkHttpCall.execute()会调用 OkHttp.Call.execute()执行同步请求
Response 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;
}
}
}
GsonConverterFactory 把网络请求返回的 Response 转成 T 对象
public final class GsonConverterFactory extends Converter.Factory {
@Override
public Converter responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
TypeAdapter> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonResponseBodyConverter<>(gson, adapter);
}
}
final class GsonResponseBodyConverter implements Converter {
private final Gson gson;
private final TypeAdapter adapter;
GsonResponseBodyConverter(Gson gson, TypeAdapter 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();
}
}
}
工厂模式,方便使用者根据需要自定义实现对应功能
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 TypeAdapter create (Gson gson, TypeToken type) {
Class rawType = (Class) type.getRawType();
if (rawType == String.class) {
return (TypeAdapter) new StringNullAdapter();
} else if (rawType == Integer.class) {
return (TypeAdapter) new IntegerNullAdapter();
} else if (rawType == Double.class) {
return (TypeAdapter) new DoubleNullAdapter();
} else if (rawType == Float.class) {
return (TypeAdapter) new FloatNullAdapter();
} else if (rawType == Long.class) {
return (TypeAdapter) new LongNullAdapter();
}
return null;
}
class StringNullAdapter extends TypeAdapter {
@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 {
@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 {
@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 {
@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 {
@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