1、从Retrofit源码分析之一,可知retrofit创建时使用代理,接下来分析一下代码:
public <T> T create(final Class<T> service) {
//校验是否为接口,且不能继承其他接口
Utils.validateServiceInterface(service);
// 是否需要提前解析接口方法
if (validateEagerly) {
eagerlyValidateMethods(service);
}
//动态代理,返回一个 service 接口的代理对象
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();
private final Object[] emptyArgs = new Object[0];
@Override public @Nullable Object invoke(Object proxy, Method method,
@Nullable Object[] args) throws Throwable {
// If the method is a method from Object then defer to normal invocation.
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}
});
}
重点看一下代理里中的invoke方法,里面return一个loadServiceMethod.invoke
在代理中,会根据参数中传入的具体接口方法来构造出对应的 serviceMethod
。ServiceMethod
类的作用就是把接口的方法适配为对应的 HTTP 请求
ServiceMethod<?> loadServiceMethod(Method method) {
//先从缓存中取,若没有就去创建对应的 ServiceMethod
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;
}
可以看出内部还维护了一个 serviceMethodCache
来缓存 ServiceMethod
,同一个 API 的同一个方法,只会创建一次
接下来看parseannotation方法:
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
//将接口传入请求工厂RequestFactory,解析注解
RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
//判断返回类型,返回类型不能包含类型变量或通配符,不能为void
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.");
}
//将接口方法的调用调整为HTTP调用
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
2、RequestFactory,作用是将接口注解解析,供http调用
final class RequestFactory {
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();
// 接口方法参数的注解
this.parameterAnnotationsArray = method.getParameterAnnotations();
}
RequestFactory build() {
//遍历接口方法注解,并解析
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
****省略代码
//遍历参数注解
int parameterCount = parameterAnnotationsArray.length;
parameterHandlers = new ParameterHandler<?>[parameterCount];
for (int p = 0, lastParameter = parameterCount - 1; p < parameterCount; p++) {
parameterHandlers[p] =
parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p], p == lastParameter);
}
****省略代码
}
如果是kotlin代码是通过isKotlinSuspendFunction来判断,Continuation在Kotlin里有一个对应interface
if (Utils.getRawType(parameterType) == Continuation.class) {
isKotlinSuspendFunction = true;
return null;
}
3、HttpServiceMethod,将接口方法的调用调整为HTTP调用,并适配不同平台
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction;
boolean continuationWantsResponse = false;
boolean continuationBodyNullable = false;
Annotation[] annotations = method.getAnnotations();
Type adapterType;
//判断是否为kotlin接口
if (isKotlinSuspendFunction) {
Type[] parameterTypes = method.getGenericParameterTypes();
Type responseType = Utils.getParameterLowerBound(0,
(ParameterizedType) parameterTypes[parameterTypes.length - 1]);
if (getRawType(responseType) == Response.class && responseType instanceof ParameterizedType) {
// Unwrap the actual body type from Response<T>.
responseType = Utils.getParameterUpperBound(0, (ParameterizedType) responseType);
continuationWantsResponse = true;
} else {
// TODO figure out if type is nullable or not
// Metadata metadata = method.getDeclaringClass().getAnnotation(Metadata.class)
// Find the entry for method
// Determine if return type is nullable or not
}
adapterType = new Utils.ParameterizedTypeImpl(null, Call.class, responseType);
annotations = SkipCallbackExecutorImpl.ensurePresent(annotations);
} else {
adapterType = method.getGenericReturnType();
}
CallAdapter<ResponseT, ReturnT> callAdapter =
createCallAdapter(retrofit, method, adapterType, annotations);
Type responseType = callAdapter.responseType();
if (responseType == okhttp3.Response.class) {
throw methodError(method, "'"
+ getRawType(responseType).getName()
+ "' is not a valid response body type. Did you mean ResponseBody?");
}
if (responseType == Response.class) {
throw methodError(method, "Response must include generic type (e.g., Response<String>)");
}
// TODO support Unit for Kotlin?
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);
//将默认的网络请求执行器(OkHttpCall)转换成适合被不同平台来调用的网络请求执行器形式
okhttp3.Call.Factory callFactory = retrofit.callFactory;
if (!isKotlinSuspendFunction) {
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
} else if (continuationWantsResponse) {
//noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForResponse<>(requestFactory,
callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter);
} else {
//noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForBody<>(requestFactory,
callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter,
continuationBodyNullable);
}
}