Retrofit 源码分析
之前分析了 Okhttp 的源码,现在来分析 Retrofit 的源码。
官方文档中,对 Retrofit 的定义是 :
A type-safe HTTP client for Android and Java.
安卓和 Java 中的一个类型安全的 HTTP 客户端。
实际上,Retrofit 是一个 RESTful 的 HTTP 网络请求框架的封装。Retrofit 2.0 开始内置 OkHttp 。该库更注重请求业务的封装。其主要核心实现是动态代理 。
官网:Retrofit (square.github.io)
Github:square/retrofit: A type-safe HTTP client for Android and the JVM (github.com)
项目中分了几个 module
- retrofit 核心 module
- adapters 适配器,主要是为了扩展性,其他库可以通过引入该库为 retrofit 添加自定义功能
- coverters 装饰器,主要是为了转换数据类型,比如你可以使用 gson 的 coveter 来将返回的 json 字符串转变为实体类
- mock 测试用,这里不分析
- samples 例子,这里不分析,但可能拿出来作为用法说明
首先我们先看看 Retrofit 库的用法,来到 sample 中 SimpleService 文件:
首先是一个 interface 接口
public interface GitHub {
@GET("/repos/{owner}/{repo}/contributors")
Call<List<Contributor>> contributors(@Path("owner") String owner, @Path("repo") String repo);
}
这里的 Contributor 是一个 POJO:
public static class Contributor {
public final String login;
public final int contributions;
public Contributor(String login, int contributions) {
this.login = login;
this.contributions = contributions;
}
}
然后我们就可以使用 Retrofit 来构造代理对象:
// Create a very simple REST adapter which points the GitHub API.
Retrofit retrofit =
new Retrofit.Builder()
.baseUrl(API_URL)
.addConverterFactory(GsonConverterFactory.create()) // 添加 gson 装饰器
.build();
// Create an instance of our GitHub API interface.
GitHub github = retrofit.create(GitHub.class); // 创建对象
然后调用该对象的方法返回 Call 对象,然后就可以发送请求了:
// Create a call instance for looking up Retrofit contributors.
Call<List<Contributor>> call = github.contributors("square", "retrofit");
// Fetch and print a list of the contributors to the library.
List<Contributor> contributors = call.execute().body();
for (Contributor contributor : contributors) {
System.out.println(contributor.login + " (" + contributor.contributions + ")");
}
让我们回到该接口:
public interface GitHub {
@GET("/repos/{owner}/{repo}/contributors") // url 包括占位符
Call<List<Contributor>> contributors(@Path("owner") String owner, @Path("repo") String repo); // 参数
}
可以看到直接使用注解指定要请求的 path,包括占位符,然后参数中也通过注解向 path 注入参数。实际上这里除了 path 参数,还支持通过注解指定 header 和 body 等参数。这也就是 retrofit 的主要作用。
首先是一个最核心的 Retrofit 实体类,我们可以调用其 create 方法创建代理对象。该类使用了创建者模式,我们先来看看其创建者:
public static final class Builder {
private @Nullable okhttp3.Call.Factory callFactory; // okhttp3 请求发送的工厂
private @Nullable HttpUrl baseUrl; // base url
private final List<Converter.Factory> converterFactories = new ArrayList<>(); // 装饰者工厂列表
private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(); // 请求适配器的工厂列表(相当于过滤器)
private @Nullable Executor callbackExecutor; // 线程池
private boolean validateEagerly; // 是否在调用 create 创建代理对象时就构造所有方法的代理对象,加载方法的请求,加载同时会验证是否合法
以上是参数,可以看到还是比较好理解了,关于以上参数有各种 getter 和 setter 方法,这里省略,我们直接来到 build 方法:
public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
// 获取运行环境,根据运行环境不同 获取 defaultCallAdatper defaultConverterFactories 或 defaultExecutor
// 包括获取代理的方法也不同,这里之后还会遇到
Platform platform = Platform.get();
// 如果有指定自定义的请求工厂则用自定义
// 否则直接使用 OkhttpClient
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
// 如果有指定线程池就是用自定义
// 否则从 platform 中拿
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
// Make a defensive copy of the adapters and add the default Call adapter.
// 将 platform 中默认的 适配器 与自定义的适配器放到一起
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
List<? extends CallAdapter.Factory> defaultCallAdapterFactories =
platform.createDefaultCallAdapterFactories(callbackExecutor);
callAdapterFactories.addAll(defaultCallAdapterFactories);
// Make a defensive copy of the converters.
// 同上操作
List<? extends Converter.Factory> defaultConverterFactories =
platform.createDefaultConverterFactories();
int defaultConverterFactoriesSize = defaultConverterFactories.size();
List<Converter.Factory> converterFactories =
new ArrayList<>(1 + this.converterFactories.size() + defaultConverterFactoriesSize);
// Add the built-in converter factory first. This prevents overriding its behavior but also
// ensures correct behavior when using converters that consume all types.
// 这里还需要加入一个 BuiltInConverters 用于基本处理
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
converterFactories.addAll(defaultConverterFactories);
// 构造 retrofit 实例
// 使用了 unmodifiableList 来确保列表不可修改
return new Retrofit(
callFactory,
baseUrl,
unmodifiableList(converterFactories),
defaultConverterFactoriesSize,
unmodifiableList(callAdapterFactories),
defaultCallAdapterFactories.size(),
callbackExecutor,
validateEagerly);
}
然后来看看 create 方法:
public <T> T create(final Class<T> service) {
// 检查合法性
validateServiceInterface(service);
// 代理对象
return (T)
Proxy.newProxyInstance(
service.getClassLoader(),
new Class<?>[] {service},
new InvocationHandler() {
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);
}
// 无参数使用空数组,而不是 null
args = args != null ? args : emptyArgs;
Platform platform = Platform.get();
// 根据 platform 判断该方法是否为 default 方法,是的话使用 platform 调用
// 也就是接口带 default 的方法将不会进行任何处理,直接正常调用
// 否则调用 loadServiceMethod 后调用,这里只加载一次,第二次会获取缓存
return platform.isDefaultMethod(method)
? platform.invokeDefaultMethod(method, service, proxy, args)
: loadServiceMethod(method).invoke(args);
}
});
}
让我们先来看看 validateServiceInterface 方法,用于检查接口是否合法:
private void validateServiceInterface(Class<?> service) {
// 必须要是接口
if (!service.isInterface()) {
throw new IllegalArgumentException("API declarations must be interfaces.");
}
// 栈
Deque<Class<?>> check = new ArrayDeque<>(1);
check.add(service);
// 遍历
while (!check.isEmpty()) {
Class<?> candidate = check.removeFirst();
// 主要是判断不支持泛型
if (candidate.getTypeParameters().length != 0) {
StringBuilder message =
new StringBuilder("Type parameters are unsupported on ").append(candidate.getName());
if (candidate != service) {
message.append(" which is an interface of ").append(service.getName());
}
throw new IllegalArgumentException(message.toString());
}
// 不断获取类型,再次判断,因为接口可能有继承关系
Collections.addAll(check, candidate.getInterfaces());
}
if (validateEagerly) {
Platform platform = Platform.get();
for (Method method : service.getDeclaredMethods()) {
// 如果不是默认方法同时不是静态方法,也就是需要进行处理的方法,则直接调用 loadServiceMethod
// 将方法放入缓存
if (!platform.isDefaultMethod(method) && !Modifier.isStatic(method.getModifiers())) {
loadServiceMethod(method);
}
}
}
}
主要是判断有没有泛型,并且如果 validateEagerly 标记为真,则在这里会直接先调用 loadServiceMethod 方法。
首先先看看 platform 的 isDefaultMethod 的作用是判断接口中的方法有没有 default 修饰,这个在不同的平台和 jdk 版本中实现不同,这里不做展开。
接下来是 loadServiceMethod 方法:
// 使用 ConcurrentHashMap 防止并发冲突
private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();
ServiceMethod<?> loadServiceMethod(Method method) {
// 先从缓存拿
ServiceMethod<?> result = serviceMethodCache.get(method);
// 如果有直接返回
if (result != null) return result;
synchronized (serviceMethodCache) { // 对缓存的操作需要加锁
// 加锁后需要 double check
result = serviceMethodCache.get(method);
if (result == null) {
// 获取代理对象
result = ServiceMethod.parseAnnotations(this, method);
// 加进缓存
serviceMethodCache.put(method, result);
}
}
return result;
}
可以看到核心就是 ServiceMethod.parseAnnotations 方法,该方法传入一个 Retrofit 对象和 一个 Mthod ,返回一个 ServiceMethod 对象,主要就是发送对应请求获取结果的过程,下面来到 ServiceMethod 类,实际上这是一个抽象类:
abstract class ServiceMethod<T> {
// 静态构造方法
static <T> ServiceMethod<T> 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.");
}
// 构造 HttpServiceMethod 对象
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
// 调用方法
abstract @Nullable T invoke(Object[] args);
}
首先是 RequestFactory,这个工厂有许多参数,都和请求有关,其中有一个重点方法,就是 create 方法,如下:
final class RequestFactory {
static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
return new Builder(retrofit, method).build();
}
// 根据调用的方法参数构造 请求
okhttp3.Request create(Object[] args) throws IOException {
@SuppressWarnings("unchecked") // It is an error to invoke a method with the wrong arg types.
// 获取 工厂指定的 parameterHandlers 参数处理器
ParameterHandler<Object>[] handlers = (ParameterHandler<Object>[]) parameterHandlers;
int argumentCount = args.length;
if (argumentCount != handlers.length) {
throw new IllegalArgumentException(
"Argument count ("
+ argumentCount
+ ") doesn't match expected count ("
+ handlers.length
+ ")");
}
// 构造 RequestBuilder
// 这是一个 Request 建造器
RequestBuilder requestBuilder =
new RequestBuilder(
httpMethod,
baseUrl,
relativeUrl,
headers,
contentType,
hasBody,
isFormEncoded,
isMultipart);
// 如果是 suspend 方法,则需要少一个参数 (默认会传多一个挂起点)
if (isKotlinSuspendFunction) {
// The Continuation is the last parameter and the handlers array contains null at that index.
argumentCount--;
}
// 使用 argumentHandler 分别处理这一些参数
List<Object> argumentList = new ArrayList<>(argumentCount);
for (int p = 0; p < argumentCount; p++) {
argumentList.add(args[p]);
handlers[p].apply(requestBuilder, args[p]);
}
// 返回一个 request
return requestBuilder.get().tag(Invocation.class, new Invocation(method, argumentList)).build();
}
}
让我们再回到上面的 parseAnnotations 中,可以看到调用了 Builder 的 build 方法该方法比较复杂,我们只看部分:
static final class Builder {
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);
// ……
// 根据参数来构造 parameterHandlers
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);
}
}
}
}
可以看到对于方法上的注解,使用 parseMethodAnnotation 方法,对于参数中的注解构造了一个 parameterHandler 列表
来到 parseMethodAnnotation 方法:
private void parseMethodAnnotation(Annotation annotation) {
// 根据注解进行对应操作
if (annotation instanceof DELETE) {
parseHttpMethodAndPath("DELETE", ((DELETE) annotation).value(), false);
} else if (annotation instanceof GET) {
parseHttpMethodAndPath("GET", ((GET) annotation).value(), false);
} else if (annotation instanceof HEAD) {
parseHttpMethodAndPath("HEAD", ((HEAD) annotation).value(), false);
} else if (annotation instanceof PATCH) {
parseHttpMethodAndPath("PATCH", ((PATCH) annotation).value(), true);
} else if (annotation instanceof POST) {
parseHttpMethodAndPath("POST", ((POST) annotation).value(), true);
} else if (annotation instanceof PUT) {
parseHttpMethodAndPath("PUT", ((PUT) annotation).value(), true);
} else if (annotation instanceof OPTIONS) {
parseHttpMethodAndPath("OPTIONS", ((OPTIONS) annotation).value(), false);
} else if (annotation instanceof HTTP) {
HTTP http = (HTTP) annotation;
parseHttpMethodAndPath(http.method(), http.path(), http.hasBody());
} else if (annotation instanceof retrofit2.http.Headers) {
String[] headersToParse = ((retrofit2.http.Headers) annotation).value();
if (headersToParse.length == 0) {
throw methodError(method, "@Headers annotation is empty.");
}
headers = parseHeaders(headersToParse);
} else if (annotation instanceof Multipart) {
if (isFormEncoded) {
throw methodError(method, "Only one encoding annotation is allowed.");
}
isMultipart = true;
} else if (annotation instanceof FormUrlEncoded) {
if (isMultipart) {
throw methodError(method, "Only one encoding annotation is allowed.");
}
isFormEncoded = true;
}
}
然后是 parseParameter 方法:
private @Nullable ParameterHandler<?> parseParameter(
int p, Type parameterType, @Nullable Annotation[] annotations, boolean allowContinuation) {
ParameterHandler<?> result = null;
if (annotations != null) {
// 遍历注解
for (Annotation annotation : annotations) {
// 调用 parseParameterAnnotation 方法获取 handler
ParameterHandler<?> annotationAction =
parseParameterAnnotation(p, parameterType, annotations, annotation);
// 如果失败就跳过
if (annotationAction == null) {
continue;
}
// 同个参数只允许一个注解
if (result != null) {
throw parameterError(
method, p, "Multiple Retrofit annotations found, only one allowed.");
}
result = annotationAction;
}
}
// 判断是否是 suspend 方法,如果所有参数都失败(或者不带任何注解)并且类型为 Continuation,这说明是 suspend 方法,这里做出一些判断和标记
if (result == null) {
if (allowContinuation) {
try {
if (Utils.getRawType(parameterType) == Continuation.class) {
isKotlinSuspendFunction = true;
return null;
}
} catch (NoClassDefFoundError ignored) {
// Ignored
}
}
throw parameterError(method, p, "No Retrofit annotation found.");
}
return result;
}
parseParameterAnnotation 方法的源码有点长,一堆 esle if,我们这里只分析 Query
private ParameterHandler<?> parseParameterAnnotation(
int p, Type type, Annotation[] annotations, Annotation annotation) {
if(){ // ……
// ……
} else 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;
// 这里根据类型判断,如果是 Iterable 的子类型
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 = (ParameterizedType) type;
// 获取泛型类型也就是迭代器的内容类型
Type iterableType = Utils.getParameterUpperBound(0, parameterizedType);
// 获取装饰器,将类型转为 String
Converter<?, String> converter = retrofit.stringConverter(iterableType, annotations);
// 返回 ParameterHandler.Query 类型
return new ParameterHandler.Query<>(name, converter, encoded).iterable();
} else if (rawParameterType.isArray()) {
Class<?> arrayComponentType = boxIfPrimitive(rawParameterType.getComponentType());
Converter<?, String> converter =
retrofit.stringConverter(arrayComponentType, annotations);
return new ParameterHandler.Query<>(name, converter, encoded).array();
} else {
Converter<?, String> converter = retrofit.stringConverter(type, annotations);
return new ParameterHandler.Query<>(name, converter, encoded);
}
} else if (annotation instanceof QueryName) {
// ……
}
}
可以看到许多重复的样板代码,这里不做过多分析。
重点来到 Converter<?, String> converter = retrofit.stringConverter(iterableType, annotations);
,从 retrofit 中获取 stringConverter,实际上,对于 Body ,还有一个 BodyConverter,我们一起来看:
public <T> Converter<T, String> stringConverter(Type type, Annotation[] annotations) {
Objects.requireNonNull(type, "type == null");
Objects.requireNonNull(annotations, "annotations == null");
for (int i = 0, count = converterFactories.size(); i < count; i++) {
Converter<?, String> converter =
converterFactories.get(i).stringConverter(type, annotations, this);
if (converter != null) {
//noinspection unchecked
return (Converter<T, String>) converter;
}
}
// Nothing matched. Resort to default converter which just calls toString().
//noinspection unchecked
return (Converter<T, String>) BuiltInConverters.ToStringConverter.INSTANCE;
}
public <T> Converter<T, RequestBody> requestBodyConverter(
Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations) {
return nextRequestBodyConverter(null, type, parameterAnnotations, methodAnnotations);
}
// 获取 RequestBodyConverter
public <T> Converter<T, RequestBody> nextRequestBodyConverter(
@Nullable Converter.Factory skipPast,
Type type,
Annotation[] parameterAnnotations,
Annotation[] methodAnnotations) {
Objects.requireNonNull(type, "type == null");
Objects.requireNonNull(parameterAnnotations, "parameterAnnotations == null");
Objects.requireNonNull(methodAnnotations, "methodAnnotations == null");
int start = converterFactories.indexOf(skipPast) + 1;
for (int i = start, count = converterFactories.size(); i < count; i++) {
Converter.Factory factory = converterFactories.get(i);
Converter<?, RequestBody> converter =
factory.requestBodyConverter(type, parameterAnnotations, methodAnnotations, this);
if (converter != null) {
//noinspection unchecked
return (Converter<T, RequestBody>) converter;
}
}
StringBuilder builder =
new StringBuilder("Could not locate RequestBody converter for ").append(type).append(".\n");
if (skipPast != null) {
builder.append(" Skipped:");
for (int i = 0; i < start; i++) {
builder.append("\n * ").append(converterFactories.get(i).getClass().getName());
}
builder.append('\n');
}
builder.append(" Tried:");
for (int i = start, count = converterFactories.size(); i < count; i++) {
builder.append("\n * ").append(converterFactories.get(i).getClass().getName());
}
throw new IllegalArgumentException(builder.toString());
}
主要是为了扩展性,我们可以给 retrofit 添加各种 converter 来实现功能,例如 Gson 的序列号与反序列化。
至此,请求工厂 RequestFactory 已经构造完了,回到之前我们构造 ServiceMethod 的时候,我们最终返回了一个 HttpServiceMethod 实例,来看看该类。
abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
HttpServiceMethod(
RequestFactory requestFactory,
okhttp3.Call.Factory callFactory,
Converter<ResponseBody, ResponseT> responseConverter) {
this.requestFactory = requestFactory;
this.callFactory = callFactory;
this.responseConverter = responseConverter;
}
// 发送请求
@Override
final @Nullable ReturnT invoke(Object[] args) {
// 直接构造一个 OkhttpCall 对象,然后调用 adapter 方法
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}
// 抽象方法
protected abstract @Nullable ReturnT adapt(Call<ResponseT> call, Object[] args);
}
这里的 Call 和 OkhttpCall 都是 retrofit 做的类,用于发送请求(和 Okhttp 中的 Call 不是同一个)
OkhttpCall 之后在分析,我们先来看看 adapt 方法。我们刚刚获取 HttpServiceMethod 对象调用的是其 .parseAnnotations 方法,我们来看看:
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;
// 如果是 suspend 方法
if (isKotlinSuspendFunction) {
Type[] parameterTypes = method.getGenericParameterTypes();
Type responseType =
Utils.getParameterLowerBound(
0, (ParameterizedType) parameterTypes[parameterTypes.length - 1]);
// 如果是 Response 类型并且 带泛型
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 对象
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.");
}
// 构造 responseConverter
Converter<ResponseBody, ResponseT> responseConverter =
createResponseConverter(retrofit, method, responseType);
okhttp3.Call.Factory callFactory = retrofit.callFactory;
if (!isKotlinSuspendFunction) {
// 如果是正常方法就返回 CallAdapted 对象
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);
}
}
我们这里只看不带 suspend 的方法,这里 直接返回了一个 new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
一个 CallAdapted 对象,同时将 callAdapter 与 responseCoverter 也放入。
我们来到 CallAdapted:
static final class CallAdapted<ResponseT, ReturnT> extends HttpServiceMethod<ResponseT, ReturnT> {
private final CallAdapter<ResponseT, ReturnT> callAdapter;
CallAdapted(
RequestFactory requestFactory,
okhttp3.Call.Factory callFactory,
Converter<ResponseBody, ResponseT> responseConverter,
CallAdapter<ResponseT, ReturnT> callAdapter) {
super(requestFactory, callFactory, responseConverter);
this.callAdapter = callAdapter;
}
// adpt 方法
@Override
protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
return callAdapter.adapt(call);
}
}
最终调用的是 callAdapter.adapt 方法。回到刚刚的方法,我们可以看到 callAdapter 需要调用 createCallAdapter 方法构造,来到该方法:
private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
Retrofit retrofit, Method method, Type returnType, Annotation[] annotations) {
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.callAdapter 方法:
public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
public CallAdapter<?, ?> nextCallAdapter(
@Nullable CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) {
Objects.requireNonNull(returnType, "returnType == null");
Objects.requireNonNull(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;
}
}
StringBuilder builder =
new StringBuilder("Could not locate call adapter for ").append(returnType).append(".\n");
if (skipPast != null) {
builder.append(" Skipped:");
for (int i = 0; i < start; i++) {
builder.append("\n * ").append(callAdapterFactories.get(i).getClass().getName());
}
builder.append('\n');
}
builder.append(" Tried:");
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
builder.append("\n * ").append(callAdapterFactories.get(i).getClass().getName());
}
throw new IllegalArgumentException(builder.toString());
}
让我们回到最初的 builder,我们发现 callAdapterFactories 是一个列表,存有许多 CallAdapter.Factory,而我们最初加入了默认的 adapter:
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
List<? extends CallAdapter.Factory> defaultCallAdapterFactories =
platform.createDefaultCallAdapterFactories(callbackExecutor);
callAdapterFactories.addAll(defaultCallAdapterFactories);
从 platform 中获取的,这里我们主要看 Android24 中的该方法:
@Override
List<? extends CallAdapter.Factory> createDefaultCallAdapterFactories(
@Nullable Executor callbackExecutor) {
return asList(
new CompletableFutureCallAdapterFactory(),
new DefaultCallAdapterFactory(callbackExecutor));
}
可以看到有两个 Factory ,一个是 CompletableFutureCallAdapterFactory,一个是 DefaultCallAdapterFactory,其中还传入了一个 callbackExecutor
这个如果没有指定,同样也是从 platform 中获取,我们来到 Android24 该方法:
Executor defaultCallbackExecutor() {
return MainThreadExecutor.INSTANCE;
}
private static final class MainThreadExecutor implements Executor {
static final Executor INSTANCE = new MainThreadExecutor();
private final Handler handler = new Handler(Looper.getMainLooper());
@Override
public void execute(Runnable r) {
handler.post(r);
}
}
就是一个 handler,只用了 MainLooper,也就是回到主线程的 Excutor。
接下来我们来看看 CompletableFutureCallAdapterFactory:
不过在此之前先来看看 CallAdapter.Factory 的接口:
abstract class Factory {
/**
* Returns a call adapter for interface methods that return {@code returnType}, or null if it
* cannot be handled by this factory.
*/
// 获取 CallAdapter
public abstract @Nullable CallAdapter<?, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit);
/**
* Extract the upper bound of the generic parameter at {@code index} from {@code type}. For
* 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);
}
/**
* Extract the raw class type from {@code type}. For example, the type representing {@code
* List<? extends Runnable>} returns {@code List.class}.
*/
protected static Class<?> getRawType(Type type) {
return Utils.getRawType(type);
}
}
现在我们来看看 CompletableFutureCallAdapterFactory:
final class CompletableFutureCallAdapterFactory extends CallAdapter.Factory {
@Override
public @Nullable CallAdapter<?, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit) {
// 这里返回值类型必须为 CompletableFuture 类型的才有返回,否则来到下一个
if (getRawType(returnType) != CompletableFuture.class) {
return null;
}
if (!(returnType instanceof ParameterizedType)) {
throw new IllegalStateException(
"CompletableFuture return type must be parameterized"
+ " as CompletableFuture<Foo> or CompletableFuture<? extends Foo>");
}
Type innerType = getParameterUpperBound(0, (ParameterizedType) returnType);
// 返回值不是 Response (CompletableFuture<Response<*>>) 类型,使用 BodyCallAdapter
if (getRawType(innerType) != Response.class) {
// 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.
// Response 类型需要带泛型
if (!(innerType instanceof ParameterizedType)) {
throw new IllegalStateException(
"Response must be parameterized" + " as Response<Foo> or Response<? extends Foo>");
}
// 获取泛型的类型
Type responseType = getParameterUpperBound(0, (ParameterizedType) innerType);
// 使用 ResponseCallAdapter
return new ResponseCallAdapter<>(responseType);
}
//……
}
这里主要是调用传入的 Call 对象的 enqueue 方法,并将结果拿到 future 对象中,其他具体就不展开(关于 结果 的 Cover 在 call 中就直接处理)。
如果我们返回值类型不为 CompletableFuture,则会来到第二个 CallAdapter.Factory,也就是 DefaultCallAdapterFactory:
final class DefaultCallAdapterFactory extends CallAdapter.Factory {
private final @Nullable Executor callbackExecutor;
DefaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
this.callbackExecutor = callbackExecutor;
}
@Override
public @Nullable CallAdapter<?, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit) {
// 只有返回值为 Call 类型的才能返回
if (getRawType(returnType) != Call.class) {
return null;
}
// 必须包含泛型
if (!(returnType instanceof ParameterizedType)) {
throw new IllegalArgumentException(
"Call return type must be parameterized as Call<Foo> or Call<? extends Foo>");
}
final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType) returnType);
// 是否含有 SkipCallbackExecutor 注解
final Executor executor =
Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class)
? null
: callbackExecutor;
return new CallAdapter<Object, Call<?>>() {
@Override
public Type responseType() {
return responseType;
}
// 如果为 空则直接返回 call,否则返回 ExecutorCallbackCall
@Override
public Call<Object> adapt(Call<Object> call) {
return executor == null ? call : new ExecutorCallbackCall<>(executor, call);
}
};
}
}
这里 ExecutorCallbackCall 在 enqueue 中传入的回调会在对应 callback executor 中执行。这里也不展开。
实际上,这些 CallAdapter 就是根据返回值类型构造对应的请求来进行线程调度之类的,在官方中有 Call 与 CompletableFuture 的支持,对于其他类型,我们需要自己添加自己的 CallAdapter.Factory。
对于普通的方法,官方只支持 Future 和 Call 类型,但是对于 suspend 方法,我们可以直接将返回值作为方法返回值,而不用套 Call 对象,在 HttpServiceMethod 的 parseAnnotations 中有以下代码:
if (isKotlinSuspendFunction) { // 如果是挂起方法
// ……
// 使用 Call 包括原类型作为 adapterType 进入下面逻辑
adapterType = new Utils.ParameterizedTypeImpl(null, Call.class, responseType);
annotations = SkipCallbackExecutorImpl.ensurePresent(annotations);
} else {
// 普通方法直接使用返回值类型
adapterType = method.getGenericReturnType();
}
之后 adapterType 会作为寻找 CallAdapter.Factory 的依据,suspend 方法将会找到 Call 类型的处理器。
然后我们来到 Call 对象,在我们拿到 Call 对象后,我们可以使用同步或异步的方式发送请求,其结果会自动使用适配器转换,我们来看看:
首先是接口:
public interface Call<T> extends Cloneable {
Response<T> execute() throws IOException;
void enqueue(Callback<T> callback);
boolean isExecuted();
void cancel();
boolean isCanceled();
Call<T> clone();
Request request();
Timeout timeout();
}
刚刚过程我们使用的实例是 OkhttpCall 实例,先看其 execute 方法:
@Override
public Response<T> execute() throws IOException {
okhttp3.Call call;
// 同步锁
synchronized (this) {
// 防止重复启动
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
// getRawCall 会获取 Okhttp 中的 Call 对象
call = getRawCall();
}
if (canceled) {
call.cancel();
}
// 使用 call .execute 获取相应并使用 parseResponse 包装结果
return parseResponse(call.execute());
}
先来看看 getRawCall 方法:
private okhttp3.Call getRawCall() throws IOException {
okhttp3.Call call = rawCall;
// 缓存
if (call != null) return call;
// Re-throw previous failures if this isn't the first attempt.
// 合法判断
if (creationFailure != null) {
if (creationFailure instanceof IOException) {
throw (IOException) creationFailure;
} else if (creationFailure instanceof RuntimeException) {
throw (RuntimeException) creationFailure;
} else {
throw (Error) creationFailure;
}
}
// Create and remember either the success or the failure.
try {
// 调用 createRawCall 创建 Call
return rawCall = createRawCall();
} catch (RuntimeException | Error | IOException e) {
throwIfFatal(e); // Do not assign a fatal error to creationFailure.
creationFailure = e;
throw e;
}
}
private okhttp3.Call createRawCall() throws IOException {
// 使用 callFactory 创建一个 call
// 默认为 OkhttpClient
// 同时使用 requestFactory 创建一个 请求
okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
来到 parseResponse 方法:
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.
// 将原先的对象删除,以便回收,之后将新的 body 进行装饰
rawResponse =
rawResponse
.newBuilder()
.body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
.build();
int code = rawResponse.code();
// 有错误
if (code < 200 || code >= 300) {
try {
// Buffer the entire body to avoid future I/O.
ResponseBody bufferedBody = Utils.buffer(rawBody);
return Response.error(bufferedBody, rawResponse);
} finally {
rawBody.close();
}
}
// 不带 body 的请求
if (code == 204 || code == 205) {
rawBody.close();
return Response.success(null, rawResponse);
}
//使用 ExceptionCatchingResponseBody 包装
ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody);
try {
// 使用 responseConverter 进行装饰
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;
}
}
ExceptionCatchingResponseBody 实际上就是一个包装类,包装 原 ResponseBody,在读取的的时候不抛出 IO 异常,而通过一个变量储存抛出的异常,在操作结束后在判断有无异常。
然后我们来看看 responseConverter ,实际上和 CallAdapter 一样,最终还是会调用 Retrofit 的方法获取,直接来到对应方法:
public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
return nextResponseBodyConverter(null, type, annotations);
}
public <T> Converter<ResponseBody, T> nextResponseBodyConverter(
@Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
Objects.requireNonNull(type, "type == null");
Objects.requireNonNull(annotations, "annotations == null");
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) {
//noinspection unchecked
return (Converter<ResponseBody, T>) converter;
}
}
还是一致,我们来到 Retrofit.Builder 看看:
List<? extends Converter.Factory> defaultConverterFactories =
platform.createDefaultConverterFactories();
int defaultConverterFactoriesSize = defaultConverterFactories.size();
List<Converter.Factory> converterFactories =
new ArrayList<>(1 + this.converterFactories.size() + defaultConverterFactoriesSize);
// Add the built-in converter factory first. This prevents overriding its behavior but also
// ensures correct behavior when using converters that consume all types.
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
converterFactories.addAll(defaultConverterFactories);
首先是 BuiltInConverters(),然后是 我们指定的 Converter,然后是 默认的。
首先是 BuiltInConverters,主要是用于一些不用装饰的类型判断,其中如果类型为 ResponseBody ,就会返回 StreamingResponseBodyConverter 或 BufferingResponseBodyConverter,如果是 Void 或者 Unit 又会返回对应的 Converter 。
static final class StreamingResponseBodyConverter
implements Converter<ResponseBody, ResponseBody> {
static final StreamingResponseBodyConverter INSTANCE = new StreamingResponseBodyConverter();
@Override
public ResponseBody convert(ResponseBody value) {
// 直接返回
return value;
}
}
static final class BufferingResponseBodyConverter
implements Converter<ResponseBody, ResponseBody> {
static final BufferingResponseBodyConverter INSTANCE = new BufferingResponseBodyConverter();
@Override
public ResponseBody convert(ResponseBody value) throws IOException {
try {
// Buffer the entire body to avoid future I/O.
// 使用 Buffer 包一层
return Utils.buffer(value);
} finally {
value.close();
}
}
}
static final class VoidResponseBodyConverter implements Converter<ResponseBody, Void> {
static final VoidResponseBodyConverter INSTANCE = new VoidResponseBodyConverter();
@Override
public Void convert(ResponseBody value) {
// 不用返回
value.close();
return null;
}
}
static final class UnitResponseBodyConverter implements Converter<ResponseBody, Unit> {
static final UnitResponseBodyConverter INSTANCE = new UnitResponseBodyConverter();
@Override
public Unit convert(ResponseBody value) {
// 返回 Unit.INSTANCE
value.close();
return Unit.INSTANCE;
}
}
默认的 Converter 是从 Platform 中获取,我们来到 Android24 类:
@Override
List<? extends Converter.Factory> createDefaultConverterFactories() {
return singletonList(new OptionalConverterFactory());
}
为 OptionalConverterFactory() 对象,主要是对 Optional 类型的变量提供支持,返回一个可空类型,如果失败则为空。
至此,Retrofit 总体流程就大概分析完了,可喜可贺。