从Retrofit最基本的用法着手,一步步分析内部调用流程。
OkHttpClient client = new OkHttpClient();
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
public interface ApiService {
@FormUrlEncoded
@POST("user/info")
Call loadUserInfo(@FieldMap Map map);
}
Call call = retrofit.create(ApiService.class).loadUserInfo(map);
call.enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
}
@Override
public void onFailure(Call call, Throwable t) {
}
});
结合上面的例子,看看每一个步骤中源码做了哪些操作
1)new Retrofit.Builder()
Retrofit通过Builder构建,先看Retrofit.Builder的构造方法
public Builder() {
this(Platform.get());
}
Builder(Platform platform) {
this.platform = platform;
}
构造方法中保存了一个Platform对象,看看Platform是什么
class Platform {
private static final Platform PLATFORM = findPlatform();
static Platform get() {
return PLATFORM;
}
···
}
可以看到get()是获取静态成员变量PLATFORM,它又是通过findPlatform()方法获取
private static Platform findPlatform() {
try {
Class.forName("android.os.Build");
if (Build.VERSION.SDK_INT != 0) {
return new Android();
}
} catch (ClassNotFoundException ignored) {
}
try {
Class.forName("java.util.Optional");
return new Java8();
} catch (ClassNotFoundException ignored) {
}
return new Platform();
}
该方法通过反射类名是否存在判断当前运行于哪个平台,这里是Android
static class Android extends Platform {
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
@Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
if (callbackExecutor == null) throw new AssertionError();
return new ExecutorCallAdapterFactory(callbackExecutor);
}
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
defaultCallbackExecutor方法内部定义了一个线程池,CallbackExecutor顾名思义就是决定处理response回调时所处线程。这里的线程池MainThreadExecutor创建了一个主线程handler,当执行runnable时,会将任务扔到主线程执行。
defaultCallAdapterFactory方法创建一个ExecutorCallAdapterFactory对象,它继承自CallAdapter.Factory,后面再分析。
2)baseUrl(BASE_URL)
baseUrl方法其实就是将传入的url转换成okhttp3中的HttpUrl对象保存起来
public Builder baseUrl(String baseUrl) {
checkNotNull(baseUrl, "baseUrl == null");
// 调用okhttp3的HttpUrl.parse方法转换url
HttpUrl httpUrl = HttpUrl.parse(baseUrl);
if (httpUrl == null) {
throw new IllegalArgumentException("Illegal URL: " + baseUrl);
}
return baseUrl(httpUrl);
}
public Builder baseUrl(HttpUrl baseUrl) {
checkNotNull(baseUrl, "baseUrl == null");
List pathSegments = baseUrl.pathSegments();
// 检查url格式,必须是以"/"结尾
if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
}
this.baseUrl = baseUrl;
return this;
}
3)addConverterFactory(GsonConverterFactory.create())
添加转换器工厂,用于请求、响应对象的序列化和反序列化
public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
可以看看本例中传入的GsonConverterFactory,它继承Converter.Factory并实现了其中两个方法,responseBodyConverter和requestBodyConverter:
@Override
public Converter 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);
}
分别创建并返回Converter接口的实现类GsonRequestBodyConverter和GsonResponseBodyConverter。GsonRequestBodyConverter负责将请求参数转换成RequestBody,GsonResponseBodyConverter负责将ResponseBody映射成实体类。
public interface Converter {
T convert(F value) throws IOException;
}
4)client(client)
保存开头创建的OkHttpClient,实际保存okhttp3.Call.Factory接口的实现,后续调用它的newCall方法返回RealCall对象。
public Builder client(OkHttpClient client) {
return callFactory(checkNotNull(client, "client == null"));
}
public Builder callFactory(okhttp3.Call.Factory factory) {
this.callFactory = checkNotNull(factory, "factory == null");
return this;
}
5)build()
根据前面设置的参数构建Retrofit实例
public Retrofit build() {
// 可以看出baseUrl是必填参数
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
// 若开头未设置client,这里也会自动创建
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
// 若为设置callbackExecutor,则调用platform.defaultCallbackExecutor方法,通过上文可以知道,这里返回MainThreadExecutor线程池
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
// Make a defensive copy of the adapters and add the default Call adapter.
// 创建自定义的调用适配器列表的副本,并添加默认调用适配器,默认适配器中保存的线程池即MainThreadExecutor
List callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
// Make a defensive copy of the converters.
List converterFactories =
new ArrayList<>(1 + this.converterFactories.size());
// 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);
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
Retrofit构造方法
Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
List converterFactories, List callAdapterFactories,
@Nullable Executor callbackExecutor, boolean validateEagerly) {
this.callFactory = callFactory;
this.baseUrl = baseUrl;
this.converterFactories = converterFactories; // Copy+unmodifiable at call site.
this.callAdapterFactories = callAdapterFactories; // Copy+unmodifiable at call site.
this.callbackExecutor = callbackExecutor;
this.validateEagerly = validateEagerly;
}
这里传入的List为不可修改的List。validateEagerly为true的话,在后续的create方法中会立即进行解析ApiService中定义的method,该值默认为false。
以上就是Retrofit初始化时,一些主要的配置项。本例中没有使用addCallAdapterFactory,可以通过该方法配置RxJava使用(需要引入rxjava库依赖),例如:
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
上面的例子中定义了一个接口,并且声明了一个方法,Retrofit会根据这个方法上的注解、参数以及返回值进行解析,通过动态代理转换成具体的请求。
1)retrofit.create(ApiService.class)
创建定义的接口的代理实例
public T create(final Class service) {
// 对传入的类进行检查,必须是interface且没有继承扩展其他接口
Utils.validateServiceInterface(service);
// validateEagerly可在Retrofit初始化时设置,默认为false
if (validateEagerly) {
// 立即加载接口中声明的方法,将方法解析成对应的ServiceMethod对象
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 {
// 执行代理类会回调此方法。参数1为代理类实例;参数2为调用的方法;参数3为调用方法中传入的参数
···
}
});
}
2)loadUserInfo(map)
获得代理类后,调用loadUserInfo方法,返回Call对象。当执行时即触发了代理回调方法invoke()
new InvocationHandler() {
private final Platform platform = Platform.get();
@Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
throws Throwable {
// If the method is a method from Object then defer to normal invocation.
// 判断该方法所在类是否是Object
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
// isDefaultMethod默认返回false
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
// 以下三行是关键
ServiceMethod
该回调中前面对method进行合法性检查,后面三行是关键,依次分析:
ServiceMethod, ?> loadServiceMethod(Method method) {
// 先从缓存中查找(serviceMethodCache为ConcurrentHashMap,key为method,value为ServiceMethod)
ServiceMethod, ?> result = serviceMethodCache.get(method);
if (result != null) return result;
// 这里采用了双重检查锁的方式
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
// 如果缓存不存在,则新建一个再存入缓存
result = new ServiceMethod.Builder<>(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
接下来看ServiceMethod的构建方法:
Builder的构造方法
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit; // 持有retrofit引用
this.method = method; // 持有调用的method的引用
this.methodAnnotations = method.getAnnotations(); // 获取所有的注解
this.parameterTypes = method.getGenericParameterTypes(); // 获取该方法的参数的参数化的类型
this.parameterAnnotationsArray = method.getParameterAnnotations(); // 获取参数注解
}
build()方法中解析的东西比较多,拆开来看:
public ServiceMethod build() {
callAdapter = createCallAdapter();
···
}
private CallAdapter createCallAdapter() {
// 获取该method的返回值类型
Type returnType = method.getGenericReturnType();
// 检查类型合法性,若是通配符类型或类型变量类型则抛异常。注意若是参数化类型或泛型数组类型,还会检查泛型参数和数组元素类型,同样不能是通配符、类型变量类型。
if (Utils.hasUnresolvableType(returnType)) {
throw methodError(
"Method return type must not include a type variable or wildcard: %s", returnType);
}
// 该method必须有返回,不能是void
if (returnType == void.class) {
throw methodError("Service methods cannot return void.");
}
// 获取该method上的注解
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(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");
// 因为传入的skipPast为null,所以start = -1 + 1,即0
int start = callAdapterFactories.indexOf(skipPast) + 1;
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
// 本例中没有额外添加自定义的CallAdapter.Factory,所以此时callAdapterFactories中只有一个元素,即Retrofit初始化时默认添加的ExecutorCallAdapterFactory
// 若有自定义的CallAdapter.Factory,在get方法中根据returnType、annotations参数决定能否处理,不能处理则get方法返回null,继续往下遍历
CallAdapter, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
// 未找到合法的CallAdapter,则拼接异常信息抛出异常
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());
}
接着看ExecutorCallAdapterFactory的get方法:
@Override
public CallAdapter, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
// getRawType方法根据Type获取method返回值的类(判断Type属于哪种类型,再返回对应的类)
// 这里限制method的返回值必须是retrofit2.Call,不满足的话返回null,交由下一个CallAdapter.Factory处理
if (getRawType(returnType) != Call.class) {
return null;
}
// getCallResponseType先判断returnType是否是参数化类型,不是则抛异常(所以method返回的应该是Call这种形式)
// 然后返回Call中T的类型,若T为通配符类型,则返回它的邻近上界的类型
final Type responseType = Utils.getCallResponseType(returnType);
// 创建并返回CallAdapter对象
return new CallAdapter>() {
@Override public Type responseType() {
// 即返回上文获得的参数类型
return responseType;
}
@Override public Call adapt(Call call) {
// ExecutorCallbackCall可以理解为call的代理类,包装了callbackExecutor即MainThreadExecutor和这里的call
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}
到这里生成并返回callAdapter实例,之后保存response的类型
response即在method定义时设置的返回对象。例如Call,response即为String。在本例中Call,response即为UserInfo。
public ServiceMethod build() {
callAdapter = createCallAdapter();
// 这里获取保存response的类型,即Call<>的<>中参数化类型
responseType = callAdapter.responseType();
if (responseType == Response.class || responseType == okhttp3.Response.class) {
throw methodError("'"
+ Utils.getRawType(responseType).getName()
+ "' is not a valid response body type. Did you mean ResponseBody?");
}
···
}
public ServiceMethod build() {
···
responseConverter = createResponseConverter();
···
}
private Converter createResponseConverter() {
// 获取method上所有注解
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);
}
}
最终调用到retrofit的nextResponseBodyConverter方法
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");
// skipPast为null,因此这里start值为0
int start = converterFactories.indexOf(skipPast) + 1;
// 遍历converterFactories
// 从上文的构建Retrofit可以知道,第一个元素为默认的BuiltInConverters,第二个元素为本例添加的GsonConverterFactory
for (int i = start, count = converterFactories.size(); i < count; i++) {
// responseBodyConverter方法中须判断type、annotations是否是该Converter.Factory能够处理的,不能处理则返回null,遍历下一个Converter.Factory
Converter converter =
converterFactories.get(i).responseBodyConverter(type, annotations, this);
if (converter != null) {
//noinspection unchecked
return (Converter) converter;
}
}
// 未找到能够处理的converter,拼接信息抛出异常
StringBuilder builder = new StringBuilder("Could not locate ResponseBody 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());
}
① 先分析BuiltInConverters
@Override
public Converter responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
// 判断response类型,即Call中的T的类型
// response若为ResponseBody或继承自ResponseBody
if (type == ResponseBody.class) {
// 判断method上的注解是否有Streaming注解,返回对应的Converter。Streaming的作用是标记不将body转换为byte[]
// StreamingResponseBodyConverter的convert方法中直接原样返回ResponseBody,不进行额外处理
// 而BufferingResponseBodyConverter的convert方法会将ResponseBody读进Buffer中
return Utils.isAnnotationPresent(annotations, Streaming.class)
? StreamingResponseBodyConverter.INSTANCE
: BufferingResponseBodyConverter.INSTANCE;
}
// 若为Call
if (type == Void.class) {
// VoidResponseBodyConverter的convert方法中会关闭ResponseBody的字节流和清除缓冲区,最后return null
return VoidResponseBodyConverter.INSTANCE;
}
// 都不为以上类型,返回null,交由下一个Converter.Factory处理
return null;
}
Retrofit默认自带的BuiltInConverters就是判断设置的response的类型,返回对应的Converter。本例为UserInfo,因此没有符合条件的Converter,传到下一个Converter.Factory。
② 接着分析GsonConverterFactory
@Override
public Converter responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
TypeAdapter> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonResponseBodyConverter<>(gson, adapter);
}
它使用了Google Gson库将ResponseBody转换为实体类,在本例中会转换为UserInfo。
经过上面的代码,responseConverter被赋值为GsonResponseBodyConverter。回到ServiceMethod的build方法继续往下分析。
public ServiceMethod build() {
···
// 依次解析method上的注解,根据注解类型赋值httpMethod、hasBody、isMultipart、isFormEncoded等成员变量
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
// 对解析后的结果检查
if (httpMethod == null) {
throw methodError("HTTP method annotation is required (e.g., @GET, @POST, etc.).");
}
// 不带request body的method不能设置Multipart和FormUrlEncoded注解
if (!hasBody) {
if (isMultipart) {
throw methodError(
"Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
}
if (isFormEncoded) {
throw methodError("FormUrlEncoded can only be specified on HTTP methods with "
+ "request body (e.g., @POST).");
}
}
···
}
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);
if (!Void.class.equals(responseType)) {
throw methodError("HEAD method must use Void as response type.");
}
} else if (annotation instanceof PATCH) {
parseHttpMethodAndPath("PATCH", ((PATCH) annotation).value(), true);
} else if (annotation instanceof POST) {
// 本例使用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("@Headers annotation is empty.");
}
headers = parseHeaders(headersToParse);
} else if (annotation instanceof Multipart) {
if (isFormEncoded) {
throw methodError("Only one encoding annotation is allowed.");
}
isMultipart = true;
} else if (annotation instanceof FormUrlEncoded) {
// Multipart和FormUrlEncoded不能同时使用,本例使用FormUrlEncoded
if (isMultipart) {
throw methodError("Only one encoding annotation is allowed.");
}
isFormEncoded = true;
}
}
在本例为POST请求,因此传入的三个参数分别是”POST”、”user/info”、true:
private void parseHttpMethodAndPath(String httpMethod, String value, boolean hasBody) {
if (this.httpMethod != null) {
throw methodError("Only one HTTP method is allowed. Found: %s and %s.",
this.httpMethod, httpMethod);
}
this.httpMethod = httpMethod;
this.hasBody = hasBody;
if (value.isEmpty()) {
return;
}
// Get the relative URL path and existing query string, if present.
int question = value.indexOf('?');
// 判断url是否带"?"和"key=value&key=value"
if (question != -1 && question < value.length() - 1) {
// Ensure the query string does not have any named parameters.
// 对于url后拼接的k=v query参数,不能使用"{}"占位,若需要使用的话可以通过Query注解
String queryParams = value.substring(question + 1);
Matcher queryParamMatcher = PARAM_URL_REGEX.matcher(queryParams);
if (queryParamMatcher.find()) {
throw methodError("URL query string \"%s\" must not have replace block. "
+ "For dynamic query parameters use @Query.", queryParams);
}
}
// 这里相对url即赋值为"user/info"
this.relativeUrl = value;
// 若url path中有用到"{}"占位,将路径参数保存在这个Set中
this.relativeUrlParamNames = parsePathParameters(value);
}
执行到这里解析完了method上的注解,然后开始解析method参数上的注解。
public ServiceMethod build() {
···
// 获取参数个数
int parameterCount = parameterAnnotationsArray.length;
parameterHandlers = new ParameterHandler>[parameterCount];
for (int p = 0; p < parameterCount; p++) {
// 获取参数类型
Type parameterType = parameterTypes[p];
// 与检查method的returnType一样检查类型
if (Utils.hasUnresolvableType(parameterType)) {
throw parameterError(p, "Parameter type must not include a type variable or wildcard: %s",
parameterType);
}
// 获取对应参数上的注解
Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
if (parameterAnnotations == null) {
throw parameterError(p, "No Retrofit annotation found.");
}
// 传入当前索引、参数类型、参数上注解,构造parameterHandlers对象
parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
}
···
}
Retrofit利用ParameterHandler对象保存和处理method中的参数上的注解,看看它是如何构造的:
private ParameterHandler> parseParameter(
int p, Type parameterType, Annotation[] annotations) {
ParameterHandler> result = null;
// 遍历注解
for (Annotation annotation : annotations) {
ParameterHandler> annotationAction = parseParameterAnnotation(
p, parameterType, annotations, annotation);
// 过滤非Retrofit定义的注解
if (annotationAction == null) {
continue;
}
// 一个参数最多只能有一个Retrofit的注解
if (result != null) {
throw parameterError(p, "Multiple Retrofit annotations found, only one allowed.");
}
result = annotationAction;
}
// 该参数上一个Retrofit的注解都没有
if (result == null) {
throw parameterError(p, "No Retrofit annotation found.");
}
// 返回构造的ParameterHandler对象
return result;
}
又调用parseParameterAnnotation方法,依次传入注解解析:
(该方法比较长,就不贴出完整代码)
private ParameterHandler> parseParameterAnnotation(
int p, Type type, Annotation[] annotations, Annotation annotation) {
// 以下判断根据不同的注解创建返回对应的ParameterHandler子类,本例使用了FieldMap注解,会创建ParameterHandler.FieldMap对象
if (annotation instanceof Url) {
// 1.先检查是否有不同的注解使用冲突
// 2.赋值gotUrl成员变量为true
// 3.判断参数类型是否为HttpUrl、String、URI、Uri,是则创建返回RelativeUrl对象,否则抛异常
} else if (annotation instanceof Path) {
// 1.先检查是否有不同的注解使用冲突
// 2.赋值gotPath成员变量为true
// 3.取出Path注解的value,校验value是否合法和relativeUrlParamNames中是否存在占位相同的名称
// 4.获取Converter。遍历converterFactories,根据type和annotations查找Converter,若没有合适的Converter,则使用默认的ToStringConverter对象
// 5.创建ParameterHandler.Path对象并传入Path注解的value、encoded和上面的converter,最后返回ParameterHandler.Path
} else if (annotation instanceof Query) {
// 1.取出Query注解的value、encoded,gotQuery成员变量赋值为true
// 2.同上获取到ToStringConverter,创建ParameterHandler.Query对象并传入Query注解的value、encoded和converter,最后返回ParameterHandler.Query
} else if (annotation instanceof QueryName) {
// 1.取出QueryName注解的encoded,gotQuery成员变量赋值为true
// 2.同上获取到ToStringConverter,创建ParameterHandler.QueryName对象并传入Query注解的value、encoded和converter,最后返回ParameterHandler.QueryName
} else if (annotation instanceof QueryMap) {
// 1.检查参数是否合法,必须是Map且key为String类型
// 2.通过Map中value的类型获取Converter,这里同上获取到ToStringConverter
// 3.创建ParameterHandler.QueryMap并传入QueryMap注解的encoded和converter,最后返回
} else if (annotation instanceof Header) {
// 与上面类似,不再一一分析。都是判断参数类型或参数化类型中的泛型类型,获取converter,再创建返回ParameterHandler对应子类。
} else if (annotation instanceof HeaderMap) {
} else if (annotation instanceof Field) {
} else if (annotation instanceof FieldMap) {
} else if (annotation instanceof Part) {
} else if (annotation instanceof PartMap) {
} else if (annotation instanceof Body) {
}
return null; // Not a Retrofit annotation.
}
parseParameterAnnotation方法中判断不同的注解类型创建对应的ParameterHandler子类,若不是Retrofit中定义的注解则返回null。
这里单独分析下本例使用的FieldMap注解:
else if (annotation instanceof FieldMap) {
// 在parseMethodAnnotation方法中判断FormUrlEncoded注解时设置isFormEncoded为true
// 使用FieldMap注解,必须同时使用FormUrlEncoded注解
if (!isFormEncoded) {
throw parameterError(p, "@FieldMap parameters can only be used with form encoding.");
}
// 获取该参数的class,若参数为泛型或数组或通配符,则获取泛型的类型的class或元素的class或邻近父类的class
Class> rawParameterType = Utils.getRawType(type);
// 比较参数的class,必须是Map或其子类
if (!Map.class.isAssignableFrom(rawParameterType)) {
throw parameterError(p, "@FieldMap parameter type must be Map.");
}
Type mapType = Utils.getSupertype(type, rawParameterType, Map.class);
// 比较参数的Type,必须是参数化类型,即有<>
if (!(mapType instanceof ParameterizedType)) {
throw parameterError(p,
"Map must include generic types (e.g., Map)" );
}
ParameterizedType parameterizedType = (ParameterizedType) mapType;
// 获取Map中key的类型
Type keyType = Utils.getParameterUpperBound(0, parameterizedType);
if (String.class != keyType) {
throw parameterError(p, "@FieldMap keys must be of type String: " + keyType);
}
// 获取Map中value的类型
Type valueType = Utils.getParameterUpperBound(1, parameterizedType);
// 根据value的类型查找converter,这里取到的是ToStringConverter
Converter, String> valueConverter =
retrofit.stringConverter(valueType, annotations);
// 赋值gotField成员变量为true
gotField = true;
// 创建返回ParameterHandler.FieldMap对象
return new ParameterHandler.FieldMap<>(valueConverter, ((FieldMap) annotation).encoded());
}
执行到这里每个ParameterHandler对应一个参数的注解解析,依次保存在parameterHandlers数组中。
接着看ServiceMethod的构建中剩下的代码:
public ServiceMethod build() {
···
// 对配合使用的注解的检查,有的注解需要配合使用,有的注解不能同时使用。在上面的解析过程中也会进行部分检查。
if (relativeUrl == null && !gotUrl) {
throw methodError("Missing either @%s URL or @Url parameter.", httpMethod);
}
if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
throw methodError("Non-body HTTP method cannot contain @Body.");
}
if (isFormEncoded && !gotField) {
throw methodError("Form-encoded method must contain at least one @Field.");
}
if (isMultipart && !gotPart) {
throw methodError("Multipart method must contain at least one @Part.");
}
return new ServiceMethod<>(this);
}
到这里分析完了ServiceMethod的创建过程,回到Retrofit的create方法中继续往下分析。
ServiceMethod serviceMethod =
(ServiceMethod) loadServiceMethod(method);
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.adapt(okHttpCall);
OkHttpCall构造方法
OkHttpCall(ServiceMethod serviceMethod, @Nullable Object[] args) {
this.serviceMethod = serviceMethod; // 持有loadServiceMethod返回的serviceMethod
this.args = args; // 持有调用loadUserInfo接口方法传入的参数args
}
OkHttpCall实现了retrofit2.Call接口,retrofit2.Call和okhttp3.Call方法类似,作用相当于对okhttp3做了一层装饰。
serviceMethod.adapt(okHttpCall),本例转换为Call返回。
T adapt(Call call) {
return callAdapter.adapt(call);
}
调用了serviceMethod构建时获取的callAdapter中的adapt方法:
@Override public Call adapt(Call call) {
// ExecutorCallbackCall可以理解为call的代理类,包装了callbackExecutor即MainThreadExecutor和这里的call
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
最终返回ExecutorCallbackCall对象。
3)call.enqueue(myCallback)
加入异步队列发起请求,这里的call即上文创建的ExecutorCallbackCall。
@Override public void enqueue(final Callback callback) {
checkNotNull(callback, "callback == null");
// 调用委托类,即OkHttpCall的enqueue方法
delegate.enqueue(new Callback() {
@Override public void onResponse(Call call, final Response response) {
// callbackExecutor为MainThreadExecutor,该线程池持有主线程handler,调用execute方法时会将runnable通过handler扔到主线程执行
callbackExecutor.execute(new Runnable() {
@Override public void run() {
if (delegate.isCanceled()) {
// Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation.
// 模拟OkHttp在取消时抛出/传递IOException的行为
callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
} else {
// 将response回调传递出去
callback.onResponse(ExecutorCallbackCall.this, response);
}
}
});
}
@Override public void onFailure(Call call, final Throwable t) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
// 在主线程回调onFailure
callback.onFailure(ExecutorCallbackCall.this, t);
}
});
}
});
}
接下来看OkHttpCall.enqueue方法
@Override public void enqueue(final Callback callback) {
checkNotNull(callback, "callback == null");
okhttp3.Call call;
Throwable failure;
synchronized (this) {
// executed成员变量标识是否已执行
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
call = rawCall;
failure = creationFailure;
// 开始默认都为空
if (call == null && failure == null) {
try {
// 创建okhttp3.Call对象
call = rawCall = createRawCall();
} catch (Throwable t) {
throwIfFatal(t);
failure = creationFailure = t;
}
}
}
// 若createRawCall这步发生异常,则回调onFailure,然后结束
if (failure != null) {
callback.onFailure(this, failure);
return;
}
// canceled成员变量标识是否已取消该请求,默认为false,可通过cancel()取消请求并将其置为true
if (canceled) {
// 调用okhttp3.Call的cancel方法
call.cancel();
}
// 最终调用okhttp3.Call的enqueue发起异步请求
call.enqueue(new okhttp3.Callback() {
@Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
Response response;
try {
// 解析okhttp3.Response,转换为retrofit2.Response返回
response = parseResponse(rawResponse);
} catch (Throwable e) {
// 解析发生异常,调用失败回调
callFailure(e);
return;
}
try {
// onResponse回调,将转换后的response传出
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();
}
}
});
}
可以看出enqueue方法就是创建okhttp3.Call对象,再调用它的enqueue方法,在onResponse回调中将okhttp3.Response转换为retrofit2.Response。
private okhttp3.Call createRawCall() throws IOException {
// 通过serviceMethod来创建okhttp3.Call
okhttp3.Call call = serviceMethod.toCall(args);
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
ServiceMethod的toCall方法:
/** Builds an HTTP request from method arguments. */
okhttp3.Call toCall(@Nullable Object... args) throws IOException {
RequestBuilder requestBuilder = new RequestBuilder(httpMethod, baseUrl, relativeUrl, headers,
contentType, hasBody, isFormEncoded, isMultipart);
@SuppressWarnings("unchecked") // It is an error to invoke a method with the wrong arg types.
ParameterHandler[] handlers = (ParameterHandler[]) parameterHandlers;
// 校验参数个数和ParameterHandler个数是否一致
int argumentCount = args != null ? args.length : 0;
if (argumentCount != handlers.length) {
throw new IllegalArgumentException("Argument count (" + argumentCount
+ ") doesn't match expected count (" + handlers.length + ")");
}
// 遍历parameterHandlers,依次调用ParameterHandler的apply方法
for (int p = 0; p < argumentCount; p++) {
handlers[p].apply(requestBuilder, args[p]);
}
// 这里callFactory即为OkHttpClient实例,调用OkHttpClient的newCall方法创建okhttp3.Call
// requestBuilder.build()方法中会保存的参数根据构建HttpUrl和RequestBody,最后再构建okhttp3.Request
return callFactory.newCall(requestBuilder.build());
}
ParameterHandler的apply方法为抽象方法,由其子类具体实现。本例中定义的参数为@FieldMap Map
@Override void apply(RequestBuilder builder, @Nullable Map value)
throws IOException {
if (value == null) {
throw new IllegalArgumentException("Field map was null.");
}
// 遍历Map
for (Map.Entry entry : value.entrySet()) {
String entryKey = entry.getKey();
if (entryKey == null) {
throw new IllegalArgumentException("Field map contained null key.");
}
T entryValue = entry.getValue();
if (entryValue == null) {
throw new IllegalArgumentException(
"Field map contained null value for key '" + entryKey + "'.");
}
// 通过Converter.convert方法将Map中的value转换为String类型
String fieldEntry = valueConverter.convert(entryValue);
if (fieldEntry == null) {
throw new IllegalArgumentException("Field map value '"
+ entryValue
+ "' converted to null by "
+ valueConverter.getClass().getName()
+ " for key '"
+ entryKey
+ "'.");
}
// 将key、value保存进RequestBuilder的formBuilder成员中,formBuilder使用两个ArrayList分别来保存key、value。encoded表示是否对key、value做Encoded处理
builder.addFormField(entryKey, fieldEntry, encoded);
}
}
}
apply方法中的valueConverter即为ToStringConverter:
@Override public String convert(Object value) {
return value.toString();
}
这里先看下retrofit2.Response类:
public final class Response<T> {
private final okhttp3.Response rawResponse; // 持有响应的okhttp3.Response对象
private final @Nullable T body; // HTTP请求正常情况下,持有定义的泛型对象
private final @Nullable ResponseBody errorBody; // HTTP请求错误下,持有okhttp3.ResponseBody对象
···
}
OkHttpCall的parseResponse方法:
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.
// 复制一个ResponseBody,将body成员替换为NoContentResponseBody对象
rawResponse = rawResponse.newBuilder()
.body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
.build();
// 获取HTTP状态码
int code = rawResponse.code();
if (code < 200 || code >= 300) {
try {
// Buffer the entire body to avoid future I/O.
// 新创建一个ResponseBody保存body
ResponseBody bufferedBody = Utils.buffer(rawBody);
// 返回retrofit2.Response对象,rawResponse赋值为rawResponse、body赋值为null、errorBody赋值为bufferedBody
return Response.error(bufferedBody, rawResponse);
} finally {
// 关闭rawBody中的BufferedSource,释放资源
rawBody.close();
}
}
// HTTP请求成功,但是没有实体返回
if (code == 204 || code == 205) {
// 关闭流、释放资源
rawBody.close();
// 创建返回retrofit2.Response,它的rawResponse成员赋值为rawResponse,其他成员均为null
return Response.success(null, rawResponse);
}
// 创建ExceptionCatchingRequestBody作为rawBody的代理类,内部有一个IOException异常变量,记录okio操作出现的IO异常
ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
try {
// 获取接口方法定义时的响应实体类,本例中为UserInfo
T body = serviceMethod.toResponse(catchingBody);
//创建返回retrofit2.Response,它的rawResponse成员赋值为rawResponse,body赋值为body,errorBody为null
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.
// 抛出记录的IOException若有
catchingBody.throwIfCaught();
throw e;
}
}
继续看ServiceMethod的toResponse方法:
/** Builds a method return value from an HTTP response body. */
R toResponse(ResponseBody body) throws IOException {
return responseConverter.convert(body);
}
这里的responseConverter即为GsonResponseBodyConverter,它的convert方法使用Gson将ResponseBody正文转换为对应的实体类,即本例中的UserInfo对象。
到这里整个请求就完成了,将转换后的retrofit2.Response通过Callback传给了调用者。