前言
看过Retrofit的应该知道,Retrofit的核心技术之一是注解+反射+动态代理,这一篇主要温故Retrofit框架的实现原理,结合上一篇泛型、反射相关文章,看一下它是如何处理收集参数的,组装请求的,再到整个流程。
需要了解注解和泛型擦除以及反射获取泛型类型相关的知识点,可以查看 通俗易懂的泛型原理及其相关知识点
目录
一、代理模式
具体分析看 代理模式
静态代理模式(普通、强制)一般会有三种角色
抽象角色:代理角色和真实角色对外提供的公共方法,一般就是接口
真实角色:实现抽象角色的接口,内部实现真正的业务逻辑
代理角色:实现抽象角色的接口,对真实角色进行代理,然后附加自己的操作,集中管理真实角色的处理
使用代理时要清楚代理模式的目的,也就是代理模式的好处,避免了外部直接访问真实对象,只能通过代理对象访问,间接达到访问目标对象,防止带来一些不必要的复杂性,统一在代理模式中调度真实对象。真实对象只关心本职业务逻辑。
项目中假如有一个场景是,实现图片加载时,考虑目前Glid加载图片的替换性,即以后可能会用其它更好的技术A替代它,你如何实现。项目在不断发展,技术也在不断更新,这也是有可能的。
然后直接设置具体的对象,使用时拿到接口对象,像早期组件化通信也会利用这种方法。
但是静态代理也有缺点,在业务开发过程中,每种业务职能对应于一个接口,每个代理类只能实现一个接口,这样写出来的代理类对象偏多,这时候就需要考虑使用动态代理了
动态代理源码分析可以见 代理模式 ,代理模式生成的类存在于内存中,我们不会看到有相关的文件生成。当然想看一下动态代理生成的内容是怎么样的,也不是不可以。
public interface ApiService {
void get();
void post();
}
public class TestProxy {
public static void main(String[] args){
String name = ApiService.class.getName()+"$Proxy0";
//源码中生成byte方式
byte[] bytes = ProxyGenerator.generateProxyClass(name,new Class[]{ApiService.class});
try {
FileOutputStream fos = new FileOutputStream("src/" + name + ".class");
fos.write(bytes);
fos.close();
}catch (Exception e){
}
}
}
生成了一个demo.ApiService$Proxy0.class 文件,内容如下
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package demo;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
public final class ApiService$Proxy0 extends Proxy implements ApiService {
private static Method m1;
private static Method m4;
private static Method m2;
private static Method m3;
private static Method m0;
public ApiService$Proxy0(InvocationHandler var1) throws {
super(var1);
}
public final boolean equals(Object var1) throws {
try {
return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final void post() throws {
try {
super.h.invoke(this, m4, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final String toString() throws {
try {
return (String)super.h.invoke(this, m2, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final void get() throws {
try {
super.h.invoke(this, m3, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final int hashCode() throws {
try {
return (Integer)super.h.invoke(this, m0, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
m4 = Class.forName("demo.ApiService").getMethod("post");
m2 = Class.forName("java.lang.Object").getMethod("toString");
m3 = Class.forName("demo.ApiService").getMethod("get");
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
上面 super.h 就是使用动态代理传递的 InvocationHandler , 具体可以查看上面代码。
二、Retrofit
注解 + 反射 + 动态代理
具体使用 Retrofit使用教程二
Retrofit从架构角度来看,本身就相当于一个工厂,将接口数据收集加工后,交给OKHttp处理,然后将返回数据包装后给使用者,能降低代码使用、代码维护风险、提高我们的开发效率,对于数据转换扩展可以和Gson或者RxJava适配。
Retrofit从技术角度来看,精髓在于反射+动态代理+注解+Convert+CallAdapter,后面两个的扩展性,导致可以完美接入RxJavaCallAdapter和自定义Convert解析数据。Convert主要用来转换数据,包括请求参数值和服务器返回的数据。CallAdapter 主要用来组装数据,放入OKHttpCall中,通过其adapt转换成我们期望返回的数据类型,就是接口方法的返回类型,如果使用了RxJavaCallAdapter,将会返回一个被观察者,有数据时通知观察者。网络请求都放在adapt方法内处理了。
1、注解收集
示例 ApiService.java
public interface ApiService {
@GET("/record")
<T> Call<BaseResponse<T>> get();
@POST("/post")
@FormUrlEncoded
Call<BaseResponse> post(@Field("key") String value);
}
使用
Retrofit retrofit = new Retrofit.Builder().baseUrl("https://www.xxx.com").build();
ApiService apiService= retrofit.create(ApiService.class);
我们调用ApiService方法时,会走到动态代理的invoke,也就是目前分析的 create 方法里的动态代理invoke方法
直接从 Retrofit的 create 方法分析
注释 1 和 注释 2 通过判断是否是 Object 的方法、还是Android或是Java系统的方法,可以避免造成无线循环调用,导致栈溢出。
注释 3 处的 loadServiceMethod 才是关键
ServiceMethod<?> loadServiceMethod(Method method) {
ServiceMethod<?> result = serviceMethodCache.get(method); // 从Map缓存取
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;
}
这个方法会先从Map里面根据 method 方法取出对应的 ServiceMethod 对象,如果没有,则通过 parseAnnotations 方法解析注解收集起来
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);//注释 1
Type returnType = method.getGenericReturnType(); // 注释 2 Method 的返回类型
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);//注释 3
}
parseAnnotations 注释 1
static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
return new Builder(retrofit, method).build();
}
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
this.methodAnnotations = method.getAnnotations();//方法上的注解标记
this.parameterTypes = method.getGenericParameterTypes();//返回一个Type对象的数组,它以声明顺序表示此Method对象表示的方法的形式参数类型
this.parameterAnnotationsArray = method.getParameterAnnotations();//获取方法参数上的注解,包括例如call(@Field("xxx) @Field("xxx2") String key)这种形式
}
可以看到,这里主要是收集方法、方法上的注解、参数Type类型、参数中所有注解。
我们再看一下它的Builder的build方法
RequestFactory build() {
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation); //这里就是 解析方法上的注解,平常使用Retrofit需要注意的规则,都会在这里校验,例如使用了方法上@FormUrlEncoded,就不能有@Multipart,然后这里还会检查注解内 的 内容正确性
}
if (httpMethod == null) {
throw methodError(method, "HTTP method annotation is required (e.g., @GET, @POST, etc.).");
}
if (!hasBody) {
if (isMultipart) {
throw methodError(method,
"Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
}
if (isFormEncoded) {
throw methodError(method, "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++) {
parameterHandlers[p] = parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p]);//注释 2
}
if (relativeUrl == null && !gotUrl) {
throw methodError(method, "Missing either @%s URL or @Url parameter.", httpMethod);
}
if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
throw methodError(method, "Non-body HTTP method cannot contain @Body.");
}
if (isFormEncoded && !gotField) {
throw methodError(method, "Form-encoded method must contain at least one @Field.");
}
if (isMultipart && !gotPart) {
throw methodError(method, "Multipart method must contain at least one @Part.");
}
return
这块主要是检查注解的使用方式是否按Retrofit的规则来,例如参数内不允许有多个 @Url 注解标记,规则具体可以查看 parseParameter 方法。然后将所有结果收集到 ParameterHandlers<?>[] 数组内,相当于一个参数对应于一个ParameterHandler ,里面存放了注解内的值,例如@Field("key") 的 key。所有这些都放在RequestFactory对象中。
当然除了规则校验,收集ParameterHandlers类,还有一个比较重要的,就是convert,在 注释 2 处 parseParameter函数内,有类似这样的代码,下面代码注释 1 处,会从Retrofit中得到Convert,保存到ParameterHandler,在之后的发起请求过程中,会调用对应的convert方法,组装数据。
if (annotation instanceof Query) {
validateResolvableType(p, type);
Query query = (Query) annotation;
String name = query.value();
boolean encoded = query.encoded();
Class<?> rawParameterType = Utils.getRawType(type);
gotQuery = true;
if (Iterable.class.isAssignableFrom(rawParameterType)) {
if (!(type instanceof ParameterizedType)) {
throw parameterError(method, p, rawParameterType.getSimpleName()
+ " must include generic type (e.g., "
+ rawParameterType.getSimpleName()
+ "<String>)");
}
ParameterizedType parameterizedType = (ParameterizedType) type;
Type iterableType = Utils.getParameterUpperBound(0, parameterizedType);
Converter<?, String> converter =
retrofit.stringConverter(iterableType, annotations); // 注释 1
return new ParameterHandler.Query<>(name, converter, encoded).iterable();
}
parseAnnotations 注释 2 getGenericReturnType 返回Type类型如下
Method[] methods = ApiService.class.getDeclaredMethods();
Type type = methods[0].getGenericReturnType();
System.out.println(type);
System.out.println(methods[0].getReturnType());
输出
retrofit2.Call<com.demo.hehe.BaseResponse<T>>
interface retrofit2.Call
true
parseAnnotations 方法先会检查返回类型,是否是按它的要求写的,例如返回 void 那肯定是不行的,返回值的写法有很多种,示例代码 ApiService 那样的,使用泛型或者不使用泛型,包括泛型类型的数组都可以,主要通过 Utils.hasUnresolveableType 检查,检查返回Type的每个元素是否符合规则(Type是否是TypeVariable、GenericArrayType、WildcardType、ParameterizedType 具体可以看上篇文章 通俗易懂的泛型原理及其相关知识点)
parseAnnotations 注释 3 开始通过 parseAnnotations 开始解析方法的注解了
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
CallAdapter<ResponseT, ReturnT> callAdapter = createCallAdapter(retrofit, method); // 注释 1 这里不分析,如果使用时没指定,那么就只有两个个 Retrofit默认的CallAdapter -> CompletableFutureCallAdapterFactory 和 ExecutorCallAdapterFactory
Type responseType = callAdapter.responseType();
if (responseType == Response.class || responseType == okhttp3.Response.class) {
throw methodError(method, "'"
+ Utils.getRawType(responseType).getName()
+ "' is not a valid response body type. Did you mean ResponseBody?");
}
if (requestFactory.httpMethod.equals("HEAD") && !Void.class.equals(responseType)) {
throw methodError(method, "HEAD method must use Void as response type.");
}
Converter<ResponseBody, ResponseT> responseConverter =
createResponseConverter(retrofit, method, responseType);//注释 2
okhttp3.Call.Factory callFactory = retrofit.callFactory;
return new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);
}
注释 1 处 的 Adapter,我们后面分析
注释 2 处 的 Converter ,我们后面分析
我们继续看返回类型 HttpServiceMethod 的 这个构造函数,就是把所有信息收集起来了
private HttpServiceMethod(RequestFactory requestFactory, okhttp3.Call.Factory callFactory,
CallAdapter<ResponseT, ReturnT> callAdapter,
Converter<ResponseBody, ResponseT> responseConverter) {
this.requestFactory = requestFactory;
this.callFactory = callFactory;
this.callAdapter = callAdapter;
this.responseConverter = responseConverter;
}
然后动态代理内loadServiceMethod 执行后 是会调用 invoke 方法,传递调用者方法内的参数,即会调用HttpServiceMethod的invoke方法
@Override ReturnT invoke(Object[] args) {
return callAdapter.adapt(
new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
}
通过OkHttpCall 将 resquestFactory中的参数名 和args中的值对应起来,如果是get请求,则在Url后面拼接起来。至此,收集完了所有参数。这个OkHttpCall是Retrofit的,并不是OkHttp的。CallAdapter会将OkHttpCall 包装后返回OkHttp的Call对象,然后就进入到了OkHttp请求阶段了。
接下来,你只需关注CallAdapter的adapt方法,看看内部具体做了什么。
2、CallAdapter
之前分析HttpServiceMethod 收集注解那里 会去获取CallAdapter
CallAdapter<ResponseT, ReturnT> callAdapter = createCallAdapter(retrofit, method);
Android这边的话,兼容Java 8+、Android API24 以上,会有两个CallAdapter,分别是CompletableFutureCallAdapterFactory 和 ExecutorCallAdapterFactory
Retrofit创建时,CallAdapter工厂添加的默认类型
@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);
}
createCallAdapter
HttpServiceMethod.java
private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
Retrofit retrofit, Method method) {
Type returnType = method.getGenericReturnType();
Annotation[] annotations = method.getAnnotations();
try {
//noinspection unchecked
return (CallAdapter<ResponseT, ReturnT>) 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.java
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;
}
}
......
throw new IllegalArgumentException(builder.toString());
}
该方法内部获取CallAdapter关键代码还是在每个CallAdapter内的get方法中。
CompletableFutureCallAdapterFactory
@Override public @Nullable CallAdapter<?, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != CompletableFuture.class) { // 返回类型 例如 A<> A是否是 CompleteFuture
return null;
}
if (!(returnType instanceof ParameterizedType)) { // 返回类型 是否是 A<> 这样的
throw new IllegalStateException("CompletableFuture return type must be parameterized"
+ " as CompletableFuture<Foo> or CompletableFuture<? extends Foo>");
}
Type innerType = getParameterUpperBound(0, (ParameterizedType) returnType);
//innerType 返回类型的上界
if (getRawType(innerType) != Response.class) { 返回类型的 是否是 Response,即返回值是 ?extend Response 这样的
// Generic type is not Response<T>. Use it for body-only adapter.
return new BodyCallAdapter<>(innerType);
}
// Generic type is Response<T>. Extract T and create the Response version of the adapter.
if (!(innerType instanceof ParameterizedType)) {
throw new IllegalStateException("Response must be parameterized"
+ " as Response<Foo> or Response<? extends Foo>");
}
Type responseType = getParameterUpperBound(0, (ParameterizedType) innerType);//获取返回类型 A<T> T 类型
return new ResponseCallAdapter<>(responseType);
}
上面这个一般不会走到,第一步就返回Null了,除非在ApiService接口定义的方法内,返回值是 CompletableFuture 类型的,需要使用到 Future 来操作请求结果,不清楚的可以先去了解Future。
DefaultCallAdapterFactory
@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<Object, Call<?>>() {
@Override public Type responseType() {
return responseType;
}
@Override public Call<Object> adapt(Call<Object> call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}
adapt方法内返回了默认的ExecutorCallbackCall,内部使用代理模式,间接调用了Retrofit的OkHttpCall,当OkHttpCall执行完后,会通过CallbackExecutor(内部就是一个主线程Handler)切换到主线程。
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;
}
@Override public void enqueue(final Callback<T> callback) {
checkNotNull(callback, "callback == null");
delegate.enqueue(new Callback<T>() {
@Override public void onResponse(Call<T> call, final Response<T> 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<T> call, final Throwable t) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
callback.onFailure(ExecutorCallbackCall.this, t);
}
});
}
});
}
@Override public Response<T> execute() throws IOException {
return delegate.execute();
}
......
}
我们最后分析一下CallAdapter 中的 泛型类型,直接看代码注释
public interface CallAdapter<R, T> {
/**
* 获取返回值类型,后期通过Convert将服务器返回的数据转换成想要的类型
*/
Type responseType();
/**
* HttpServiceMethod中invoke调用的方法,也就是每次通过Retrofit都会触发的一个方法,
*/
T adapt(Call<R> call);
abstract class Factory {
/**
* Returns a call adapter for interface methods that return {@code returnType}, or null if it
* cannot be handled by this factory.
*/
public abstract @Nullable CallAdapter<?, ?> get(Type returnType, Annotation[] annotations,
Retrofit retrofit);
/**
* 泛型上界类型
* example, index 1 of {@code Map<String, ? extends Runnable>} returns {@code Runnable}.
*/
protected static Type getParameterUpperBound(int index, ParameterizedType type) {
return Utils.getParameterUpperBound(index, type);
}
/**
* A<?> --> A
* {@code List<? extends Runnable>} returns {@code List.class}.
*/
protected static Class<?> getRawType(Type type) {
return Utils.getRawType(type);
}
}
}
结合CallAdapter 接口看一下, DefaultCallAdapterFactory 中为什么 直接 new CallAdapter<Object,Call<?>>(){} ,泛型这样写,是有目的的,相当于R -> Object,然后adapt方法内参数就是Call<Object> 返回值经过泛型擦除就行Call<Object> 了,然后直接返回 call 就不会报错。
3、Convert
HttpServiceMethod持有的responseConvert是通过这样获取的,其中responseType是通过CallAdapter获取到的
Converter<ResponseBody, ResponseT> responseConverter = createResponseConverter(retrofit, method, responseType);
createResponseConverter
private static <ResponseT> Converter<ResponseBody, ResponseT> 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);
}
}
这个方法内部会根据responseType拿到对应的Convert,在构建Retrofit时,默认添加了BuiltInConverters,它继承自Converter.Factory,我们自己自定义的也是继承自Converter.Factory类。
public interface Converter<F, T> {
@Nullable T convert(F value) throws IOException;
abstract class Factory {
//得到responseConvert时调用,后续通过HttpServiceMethod传递给OkHttpCall
public @Nullable Converter<ResponseBody, ?> responseBodyConverter(Type type,
Annotation[] annotations, Retrofit retrofit) {
return null;
}
//在处理PartMap或者Par、Body等注解时,会调用,具体见RequestFactory的 parseParameterAnnotation方法
public @Nullable Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
return null;
}
//在处理FieldMap等注解是会调用,见 parseParameterAnnotation 方法
public @Nullable Converter<?, String> stringConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
return null;
}
}
常见的GsonConvert如下,Retrofit主要是通过Convert来包装请求参数和将返回数据转换成我们定义的格式
public final class GsonConverterFactory extends Converter.Factory {
//最常使用的静态工厂方法,使用默认的Gson实例
public static GsonConverterFactory create() {
return create(new Gson());
}
//使用这个工厂方法可以从外部传入Gson对象,对Gson对象做配置
public static GsonConverterFactory create(Gson gson) {
...
return new GsonConverterFactory(gson); // -> implements Converter<T, RequestBody>
}
private final Gson gson;
private GsonConverterFactory(Gson gson) {
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); // -> implements Converter<ResponseBody, T>
}
}
4、发送请求
我们从第一点末尾,可以了解到发起请求是通过CallAdapter的adapt方法出发的,而CallAdapter的adapter方法,默认会返回ExecutorCallbackCall ,然后触发它的enqueue 方法,内部真正调用的还是OkHttpCall的enqueue方法。
@Override public void enqueue(final Callback<T> 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(); //注释 1
.....
// OKHttp开始发起请求
call.enqueue(new okhttp3.Callback() {
@Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
Response<T> response;
try {
response = parseResponse(rawResponse); //注释 2
} 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);
}
......
}
我们关注 注释 1 和 注释 2 处,注释1
private okhttp3.Call createRawCall() throws IOException {
okhttp3.Call call = callFactory.newCall(requestFactory.create(args)); //这里是invoke时传递的参数,也就是ApiService.java 中每个方法的形参值
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
requestFactory.crate 这里截取一部分
for (int p = 0; p < argumentCount; p++) {
argumentList.add(args[p]);
handlers[p].apply(requestBuilder, args[p]);
}
这里会调用apply方法,apply方法内部就是将参数值和参数名进行匹配,还记得之前Retrofit将注解值和包装参数值的 requestConvert 传递给了RequestFactory吗?这里就是传递参数值,然后构建请求Url或者将参数组装,例如ParmaeterHandler.Path类
@Override void apply(RequestBuilder builder, @Nullable T value) throws IOException {
if (value == null) {
throw new IllegalArgumentException(
"Path parameter \"" + name + "\" value must not be null.");
}
builder.addPathParam(name, valueConverter.convert(value), encoded);
}
注释2 处 parseResponse 方法,就是通过传递给OKHttpCall的responseConvert,调用其convert方法将数据解析成我们想要的类型,然后返回。
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
ResponseBody rawBody = rawResponse.body();
.......
try {
T body = responseConverter.convert(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;
}
}