Retrofit对请求方法的解析
Retrofit对我们在接口类中定义的方法是如何转换成了请求,又如何处理响应。这一切都在它的loadServiceMethod方法中
代码基于Retrofit2.5.0
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;
}
主要是调用ServiceMethod.parseAnnotations
static ServiceMethod parseAnnotations(Retrofit retrofit, Method method) {
RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);//这里就是对请求的解析,也就是我们定义的接口方法
Type returnType = method.getGenericReturnType();//获取返回的类型
//省略无关代码
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
RequestFactory.parseAnnotations这个方法就是对我们定义的接口方法的解析,在里面解析注解和使用反射得到了关于请求的所有信息。
响应的处理
在完成了对请求的处理后构建了RequestFactory类,这个类里面包含了请求的所有信息:
final class RequestFactory {
static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
return new Builder(retrofit, method).build();
}
private final Method method;
private final HttpUrl baseUrl;
final String httpMethod;
private final @Nullable String relativeUrl;
private final @Nullable Headers headers;
private final @Nullable MediaType contentType;
private final boolean hasBody;
private final boolean isFormEncoded;
private final boolean isMultipart;
private final ParameterHandler>[] parameterHandlers;
接下来继续来看ServiceMethod的parseAnnotations剩下的语句
ServiceMethod.parseAnnotations
static ServiceMethod parseAnnotations(Retrofit retrofit, Method method) {
//省略无关代码
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);//对响应的处理
}
HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory)
static HttpServiceMethod parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
CallAdapter callAdapter = createCallAdapter(retrofit, method);//创建请求适配器
Type responseType = callAdapter.responseType();
//省略无关代码
Converter responseConverter =
createResponseConverter(retrofit, method, responseType);//创建响应数据转换器(Gson)
okhttp3.Call.Factory callFactory = retrofit.callFactory;//Okhttp请求客户端
return new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);
}
创建请求适配器CallAdapter
首先进入第一行
HttpServiceMethod.createCallAdapter
private static CallAdapter createCallAdapter(
Retrofit retrofit, Method method) {
Type returnType = method.getGenericReturnType();//获取返回的类型
Annotation[] annotations = method.getAnnotations();//获取注解
try {
//noinspection unchecked
return (CallAdapter) 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
public CallAdapter, ?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
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;
}
}
}
这里面是一个循环获取请求适配器工厂数组callAdapterFactories,在retrofit创建的时候,我们可以知道往这个数组里面加的是Android平台默认的ExecutorCallAdapterFactory
public Retrofit build() {
List callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
}
static class Android extends Platform {
@Override List extends CallAdapter.Factory> defaultCallAdapterFactories(
@Nullable Executor callbackExecutor) {
if (callbackExecutor == null) throw new AssertionError();
//这里可以看到返回的类
ExecutorCallAdapterFactory executorFactory = new ExecutorCallAdapterFactory(callbackExecutor);
return Build.VERSION.SDK_INT >= 24
? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
: singletonList(executorFactory);
}
}
在刚才的循环里,调用了它的get方法,实际就是调用
ExecutorCallAdapterFactory.get
@Override public @Nullable CallAdapter, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
final Type responseType = Utils.getCallResponseType(returnType);//根据返回类型获取泛型里面的想要获取的响应类型
return new CallAdapter
我们定义的返回类型一般是泛型的形式,如Call
return new CallAdapter>() {
@Override public Type responseType() {
return responseType;
}
@Override public Call adapt(Call call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
自此就完成了CallAdapter的创建,这里记住它的adapt方法,里面是返回的ExecutorCallbackCall,这个后面会调用,再来继续看。
HttpServiceMethod的parseAnnotations第一行代码到此就完了,继续往下执行:
创建响应数据转换器(如Gson)和请求客户端
HttpServiceMethod.parseAnnotations
static HttpServiceMethod parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
CallAdapter callAdapter = createCallAdapter(retrofit, method);
Type responseType = callAdapter.responseType();//获取具体的响应类型
//省略无关代码
Converter responseConverter =
createResponseConverter(retrofit, method, responseType);
okhttp3.Call.Factory callFactory = retrofit.callFactory;
return new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);
}
注意这里传给responseConverter的responseType是我们刚才获取Call泛型里面的具体类型,也就是我们想要拿到的实体类类型。
这个过程跟刚才创建CallAdapter的过程很像,就连方法名都很像,所以来看看createResponseConverter方法:
HttpServiceMethod.createResponseConverter
private static Converter 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);
}
}
通过method的getAnnotations拿到注解列表,然后跟返回类型传入responseBodyConverter方法:
retrofit.responseBodyConverter
public Converter responseBodyConverter(Type type, Annotation[] annotations) {
return nextResponseBodyConverter(null, type, annotations);
}
public Converter 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 converter =
converterFactories.get(i).responseBodyConverter(type, annotations, this);
if (converter != null) {
//noinspection unchecked
return (Converter) converter;
}
}
这个过程简直跟刚才创建CallAdapter的过程一模一样,也是循环从converterFactories取出Converter,根据之前Retrofit的创建时我们传入的是GsonConverterFactory,所以是调用的它的responseBodyConverter方法:
GsonConverterFactory.responseBodyConverter
public Converter responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
TypeAdapter> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonResponseBodyConverter<>(gson, adapter);
}
这里的代码就很面熟了,通过TypeToken获取类型,之后返回一个Gson解析器,它的convert就是调用Gson进行泛型的解析。
GsonResponseBodyConverter
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();
}
}
}
到这里就完成了响应字符串的解析器的创建,接下来会执行
okhttp3.Call.Factory callFactory = retrofit.callFactory;
return new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);
创建okhttp请求的客户端,这里命名为callFactory,在Retrofit创建的时候我们传入的okhttpClient就是赋值给了callFactory,最后将创建好的对象传入HttpServiceMethod返回。
到此为止就执行完了HttpServiceMethod的parseAnnotations方法,在这个方法里面,创建了几个重要的东西
- 对请求和响应做具体处理的CallAdapter类,具体为ExecutorCallAdapterFactory,这里要注意它的adapt方法返回ExecutorCallbackCall类
- 响应数据解析工厂Converter,具体为GsonResponseBodyConverter
- okhttp请求客户端
发送请求
终于到了这一步了,在做好了所有的准备工作之后,最终Retrofit怎么来发送请求呢,首先一步步回到最开始的地方:
在HttpServiceMethod.parseAnnotations方法是在ServiceMethod的parseAnnotations调用的
ServiceMethod.parseAnnotations
abstract class ServiceMethod {
static ServiceMethod 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);
}
abstract T invoke(Object[] args);
}
然后ServiceMethod.parseAnnotations方法是在Retrofit的loadServiceMethod调用的
然后loadServiceMethod是在Retrofit的create方法里面创建动态代理的invoke调用的
Retrofit.create
public T create(final Class service) {
//省略无关代码
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class>[] { service },
new InvocationHandler() {
//省略无关代码
@Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
throws Throwable {
//省略无关代码
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}
});
}
可以看到,在loadServiceMethod之后调用了invoke方法,也就是ServiceMethod的invoke方法,点进去之后发现它是个ServiceMethod是个抽象类,它的invoke需要实现类来重写:
abstract class ServiceMethod {
abstract T invoke(Object[] args);
}
ServiceMethod类只有一个实现类,也就是我们刚才看到过的HttpServiceMethod,所以实际上调用的是它的invoke方法:
HttpServiceMethod.invoke
@Override ReturnT invoke(Object[] args) {
return callAdapter.adapt(
new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
}
在这里只有一行代码,实际上是调用callAdapter.adapt,那这个callAdapter是什么呢?刚才我们已经知道它是ExecutorCallAdapterFactory创建的,然后在创建的callAdapter的adapt方法返回ExecutorCallbackCall类,所以来看看这个类:
ExecutorCallbackCall是ExecutorCallAdapterFactory的静态内部类
ExecutorCallbackCall
static final class ExecutorCallbackCall implements Call {
final Executor callbackExecutor;
final Call delegate;
ExecutorCallbackCall(Executor callbackExecutor, Call delegate) {
this.callbackExecutor = callbackExecutor;
this.delegate = delegate;
}
@Override public void enqueue(final Callback callback) {
checkNotNull(callback, "callback == null");
delegate.enqueue(new Callback() {
@Override public void onResponse(Call call, final Response response) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
if (delegate.isCanceled()) {
// Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation.
callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
} else {
callback.onResponse(ExecutorCallbackCall.this, response);
}
}
});
}
@Override public void onFailure(Call call, final Throwable t) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
callback.onFailure(ExecutorCallbackCall.this, t);
}
});
}
});
}
@Override public boolean isExecuted() {
return delegate.isExecuted();
}
@Override public Response execute() throws IOException {
return delegate.execute();
}
@Override public void cancel() {
delegate.cancel();
}
@Override public boolean isCanceled() {
return delegate.isCanceled();
}
@SuppressWarnings("CloneDoesntCallSuperClone") // Performing deep clone.
@Override public Call clone() {
return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone());
}
@Override public Request request() {
return delegate.request();
}
}
在这个类里面,我们就看到了很多很熟悉的方法,enqueue方法发送请求,实际的请求和处理就是在这里面,但是还有疑惑就是具体的处理我们还是没看到,callbackExecutor和delegate这两个熟悉才是关键所在:
callbackExecutor
这个是在ExecutorCallAdapterFactory的构造方法中传入的,它的构造方法又是在Platform的defaultCallAdapterFactories方法中调用的,看到Platform,自然可以想到它的Android平台类,所以这个callbackExecutor实际上是MainThreadExecutor
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
其实代码很简单,使用了我们最常用的Handler,让代码在主线程中执行,也就是我们通常做的在子线程请求网络,主线程中更新UI。
delegate
delegate实际是在HttpServiceMethod的invoke方法里传入:
@Override ReturnT invoke(Object[] args) {
return callAdapter.adapt(
new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
}
实际上是OkHttpCall这个类,这个类里面就是发送请求和处理响应的具体处理,代码很多,我们只看看构造方法和enqueue
OkHttpCall(RequestFactory requestFactory, Object[] args,
okhttp3.Call.Factory callFactory, Converter responseConverter) {
this.requestFactory = requestFactory;//请求工厂,里面包含了请求的所有信息
this.args = args;//参数
this.callFactory = callFactory;//请求客户端,okhttp
this.responseConverter = responseConverter;//响应的json解析器(Gson)
}
OkHttpCall.enqueue
@Override public void enqueue(final Callback callback) {
checkNotNull(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 response;
try {
response = parseResponse(rawResponse);
} catch (Throwable e) {
throwIfFatal(e);
callFailure(e);
return;
}
try {
callback.onResponse(OkHttpCall.this, response);
} catch (Throwable t) {
t.printStackTrace();
}
}
@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) {
t.printStackTrace();
}
}
});
}
代码其实很简单,就是使用okhttp请求,然后在响应方法onResponse做相应的解析和处理,最后完成网络请求。
总结
Retrofit对响应的解析大概可分为
- 创建处理适配器CallAdapter,具体实现类为ExecutorCallbackCall,在这里面进行发送请求和处理响应等相关的操作,最终是调用okhttp进行网络请求
- 创建响应数据转换器Converter,具体实现类为GsonResponseBodyConverter,用于对返回json数据的解析,这个是我们自己传入的Gson解析工厂,Retrofit也支持其他的第三方解析库
- 发送请求,具体的操作类是OkHttpCall来发送请求和处理响应,MainThreadExecutor来做回调的处理,在主线程中处理已经转化好的实体类。