整体Retrofit内容如下:
- 1、Retrofit解析1之前哨站——理解RESTful
- 2、Retrofit解析2之使用简介
- 3、Retrofit解析3之反射
- 4、Retrofit解析4之注解
- 5、Retrofit解析5之代理设计模式
- 6、Retrofit解析6之面向接口编程
- 7、Retrofit解析7之相关类解析
- 8、Retrofit解析8之核心解析——ServiceMethod及注解1
- 9、Retrofit解析8之核心解析——ServiceMethod及注解2
- 10、Retrofit解析9之流程解析
- 11、Retrofit解析10之感谢
由于简述篇幅的限制,接上一篇文章继续
3.2.8、 Builder的方法parseParameter解析
看名字这个方法我们理解为解析参数的方法
private ParameterHandler> parseParameter(
int p, Type parameterType, Annotation[] annotations) {
// 定义一个ParameterHandler 变量
ParameterHandler> result = null;
//parseParameterAnnotation方法来获取对应的ParameterHandler对象
for (Annotation annotation : annotations) {
ParameterHandler> annotationAction = parseParameterAnnotation(
p, parameterType, annotations, annotation);
if (annotationAction == null) {
continue;
}
if (result != null) {
throw parameterError(p, "Multiple Retrofit annotations found, only one allowed.");
}
//对之前定义的变量赋值
result = annotationAction;
}
//非空检查
if (result == null) {
throw parameterError(p, "No Retrofit annotation found.");
}
return result;
}
这个方法内部很简单,主要就是通过遍历annotations,内部调用parseParameterAnnotation来获取ParameterHandler对象并返回。
那让我们来看看parseParameterAnnotation()方法里面是怎么调用的
3.2.9、 Builder的方法parseParameterAnnotation解析
private ParameterHandler> parseParameterAnnotation(
int p, Type type, Annotation[] annotations, Annotation annotation) {
//如果注解是 @Url
if (annotation instanceof Url) {
//默认是在这里给gotUrl赋值的,且只能赋值一次,如果gotUrl==true,则说明之前赋值过,抛异常
if (gotUrl) {
throw parameterError(p, "Multiple @Url method annotations found.");
}
//@Url 注解和@Path 是互斥的,所以不能并存,发现并存则抛异常
if (gotPath) {
throw parameterError(p, "@Path parameters may not be used with @Url.");
}
//如果已经使用了@Query、@QueryMap或者@QueryName,会出问题,因为应该先使用@Url 后才能配置Query等的注解
if (gotQuery) {
throw parameterError(p, "A @Url parameter must not come after a @Query");
}
//如果设置了relativeUrl,说明已经动态配置过url,所以这时候不能再使用@Url 注解
if (relativeUrl != null) {
throw parameterError(p, "@Url cannot be used with @%s URL", httpMethod);
}
//给gotUrl赋值为true
gotUrl = true;
//类型判断
if (type == HttpUrl.class
|| type == String.class
|| type == URI.class
|| (type instanceof Class && "android.net.Uri".equals(((Class>) type).getName()))) {
//返回ParameterHandler的静态内部类RelativeUrl
return new ParameterHandler.RelativeUrl();
//至此解析@Url 完毕
} else {
throw parameterError(p,
"@Url must be okhttp3.HttpUrl, String, java.net.URI, or android.net.Uri type.");
}
//如果是@ Path 注解
} else if (annotation instanceof Path) {
//如果已经设置了gotQuery,说明之前解析过@Query、@QueryMap或者@QueryName,这会导致动态配置的异常,所以抛异常
if (gotQuery) {
throw parameterError(p, "A @Path parameter must not come after a @Query.");
}
//上面解释过,@Path和@Url是互斥的
if (gotUrl) {
throw parameterError(p, "@Path parameters may not be used with @Url.");
}
//如果设置了relativeUrl为null,无法进行动态配置,所以会抛异常
if (relativeUrl == null) {
throw parameterError(p, "@Path can only be used with relative url on @%s", httpMethod);
}
//给gotPath赋值
gotPath = true;
//获取Path对象
Path path = (Path) annotation;
String name = path.value();
//通过正则表达式检查是否符合要求
validatePathName(p, name);
//调用retrofit的stringConverter来获取一个转换器,通过泛型我们知道这个转化器的输出是String
Converter, String> converter = retrofit.stringConverter(type, annotations);
//返回ParameterHandler的静态内部类Path对象
return new ParameterHandler.Path<>(name, converter, path.encoded());
//至此解析@Path结束
//如果是@Query 注解
} else if (annotation instanceof Query) {
//类型转化,获取对应的值
Query query = (Query) annotation;
String name = query.value();
boolean encoded = query.encoded();
//获取真实的类型
Class> rawParameterType = Utils.getRawType(type);
//给gotQuery赋值,说明已经使用了 注解
gotQuery = true;
//如果rawParameterType是Iterable接口的子类
if (Iterable.class.isAssignableFrom(rawParameterType)) {
//如果不是参数化的类型,则抛出异常
if (!(type instanceof ParameterizedType)) {
throw parameterError(p, rawParameterType.getSimpleName()
+ " must include generic type (e.g., "
+ rawParameterType.getSimpleName()
+ ")");
}
//如果是参数化的类型,则进行强制类型转化
ParameterizedType parameterizedType = (ParameterizedType) type;
//获取第一个入参的参数类型
Type iterableType = Utils.getParameterUpperBound(0, parameterizedType);
//获取输出类型是String的转化器
Converter, String> converter =
retrofit.stringConverter(iterableType, annotations);
//构建ParameterHandler的内部静态类Query,然后调用iterable()方法 获取一个新的ParameterHandler对象
return new ParameterHandler.Query<>(name, converter, encoded).iterable();
//如果类型是数组类型的
} else if (rawParameterType.isArray()) {
//如果是基本基本类型则需要装箱操作
Class> arrayComponentType = boxIfPrimitive(rawParameterType.getComponentType());
//获取输出类型是String的转化器
Converter, String> converter =
retrofit.stringConverter(arrayComponentType, annotations);
//构建ParameterHandler的内部静态类Query,然后调用array()方法 获取一个新的ParameterHandler对象。
return new ParameterHandler.Query<>(name, converter, encoded).array();
} else {
//如果既不是集合也不是数组类型,则是普通类型
//获取输出类型的是String的类型转化器
Converter, String> converter =
retrofit.stringConverter(type, annotations);
//构建ParameterHandler的内部静态类Query
return new ParameterHandler.Query<>(name, converter, encoded);
}
//自此 解析@Query 完毕
//如果是 @QueryName 注解
} else if (annotation instanceof QueryName) {
//获取QueryName 注解的值
QueryName query = (QueryName) annotation;
boolean encoded = query.encoded();
//获取原始类型
Class> rawParameterType = Utils.getRawType(type);
gotQuery = true;
//如果rawParameterType是Iterable接口的子类
if (Iterable.class.isAssignableFrom(rawParameterType)) {
if (!(type instanceof ParameterizedType)) {
throw parameterError(p, rawParameterType.getSimpleName()
+ " must include generic type (e.g., "
+ rawParameterType.getSimpleName()
+ ")");
}
//如果是参数化的类型,则进行强制类型转化
ParameterizedType parameterizedType = (ParameterizedType) type;
//获取第一个入参的参数类型
Type iterableType = Utils.getParameterUpperBound(0, parameterizedType);
//获取输出类型是String的转化器
Converter, String> converter =
retrofit.stringConverter(iterableType, annotations);
//构建ParameterHandler的内部静态类QueryName,然后调用iterable()方法 获取一个新的ParameterHandler对象。
return new ParameterHandler.QueryName<>(converter, encoded).iterable();
//如果类型是数组类型的
} else if (rawParameterType.isArray()) {
//如果是基本基本类型则需要装箱操作
Class> arrayComponentType = boxIfPrimitive(rawParameterType.getComponentType());
//获取输出类型是String的转化器
Converter, String> converter =
retrofit.stringConverter(arrayComponentType, annotations);
//构建ParameterHandler的内部静态类QueryName,然后调用array()方法 获取一个新的ParameterHandler对象。
return new ParameterHandler.QueryName<>(converter, encoded).array();
} else {
//如果既不是集合也不是数组类型,则是普通类型
//获取输出类型的是String的类型转化器
Converter, String> converter =
retrofit.stringConverter(type, annotations);
//构建ParameterHandler的内部静态类QueryName
return new ParameterHandler.QueryName<>(converter, encoded);
}
//如果是 @QueryMap 注解,
} else if (annotation instanceof QueryMap) {
//获取原始的类型
Class> rawParameterType = Utils.getRawType(type);
//如果不是Map的接口的子类,抛异常
if (!Map.class.isAssignableFrom(rawParameterType)) {
throw parameterError(p, "@QueryMap parameter type must be Map.");
}
//获取类型的超类
Type mapType = Utils.getSupertype(type, rawParameterType, Map.class);
//如果不是参数类型,则抛异常
if (!(mapType instanceof ParameterizedType)) {
throw parameterError(p, "Map must include generic types (e.g., Map)");
}
//强制类型转化
ParameterizedType parameterizedType = (ParameterizedType) mapType;
//获取第一个入参的参数类型,其实就是map中key的类型,一般是String
Type keyType = Utils.getParameterUpperBound(0, parameterizedType);
//如果不是String 类型,则抛异常
if (String.class != keyType) {
throw parameterError(p, "@QueryMap keys must be of type String: " + keyType);
}
//获取第二个参数的类型,也就是value的值
Type valueType = Utils.getParameterUpperBound(1, parameterizedType);
//获取输出是String的转化器
Converter, String> valueConverter =
retrofit.stringConverter(valueType, annotations);
//构建ParameterHandler的内部静态类QueryMap,并返回
return new ParameterHandler.QueryMap<>(valueConverter, ((QueryMap) annotation).encoded());
//如果是@Header 注解
} else if (annotation instanceof Header) {
//获取header的值
Header header = (Header) annotation;
String name = header.value();
//获取原始类型
Class> rawParameterType = Utils.getRawType(type);
//如果是Iterable的子类
if (Iterable.class.isAssignableFrom(rawParameterType)) {
//参数类型判断
if (!(type instanceof ParameterizedType)) {
throw parameterError(p, rawParameterType.getSimpleName()
+ " must include generic type (e.g., "
+ rawParameterType.getSimpleName()
+ ")");
}
ParameterizedType parameterizedType = (ParameterizedType) type;
//获取第一个参数的类型
Type iterableType = Utils.getParameterUpperBound(0, parameterizedType);
//获取输出是String 类型的转化器
Converter, String> converter =
retrofit.stringConverter(iterableType, annotations);
//构建ParameterHandler的内部静态类Header,然后调用iterable()方法 获取一个新的ParameterHandler对象
return new ParameterHandler.Header<>(name, converter).iterable();
//如果是数组类型
} else if (rawParameterType.isArray()) {
//装箱操作
Class> arrayComponentType = boxIfPrimitive(rawParameterType.getComponentType());
//获取输出为String 类型的 转换器
Converter, String> converter =
retrofit.stringConverter(arrayComponentType, annotations);
//构建ParameterHandler的内部静态类Header,然后调用array()方法 获取一个新的ParameterHandler对象。
return new ParameterHandler.Header<>(name, converter).array();
} else {
//如果既不是迭代器也不是数组,则是普通类型
//获取输出为String 类型的 转换器
Converter, String> converter =
retrofit.stringConverter(type, annotations);
//构建ParameterHandler的内部静态类Header
return new ParameterHandler.Header<>(name, converter);
}
//如果是@HeaderMap 注解
} else if (annotation instanceof HeaderMap) {
//获取参数的原始类型
Class> rawParameterType = Utils.getRawType(type);
//如果不是Map接口类型的子类,则抛异常
if (!Map.class.isAssignableFrom(rawParameterType)) {
throw parameterError(p, "@HeaderMap parameter type must be Map.");
}
//获取类型的超类
Type mapType = Utils.getSupertype(type, rawParameterType, Map.class);
//参数类型判断
if (!(mapType instanceof ParameterizedType)) {
throw parameterError(p, "Map must include generic types (e.g., Map)");
}
ParameterizedType parameterizedType = (ParameterizedType) mapType;
//获取第一个参数的类型,是key的类型
Type keyType = Utils.getParameterUpperBound(0, parameterizedType);
//key值 一定是String的,不是String 则抛异常
if (String.class != keyType) {
throw parameterError(p, "@HeaderMap keys must be of type String: " + keyType);
}
//获取value的类型
Type valueType = Utils.getParameterUpperBound(1, parameterizedType);
//获取输出是 String的转化器
Converter, String> valueConverter =
retrofit.stringConverter(valueType, annotations);
//构建ParameterHandler的内部静态类HeaderMap
return new ParameterHandler.HeaderMap<>(valueConverter);
// 如果是 @Field
} else if (annotation instanceof Field) {
// 如果没有使用方法注解 @isFormEncoded,却使用参数注解@Field,则抛出异常
if (!isFormEncoded) {
throw parameterError(p, "@Field parameters can only be used with form encoding.");
}
// 获取 注解的内容
Field field = (Field) annotation;
String name = field.value();
boolean encoded = field.encoded();
// 给gotField赋值
gotField = true;
//获取原始类型
Class> rawParameterType = Utils.getRawType(type);
// 如果是Iterable类的子类
if (Iterable.class.isAssignableFrom(rawParameterType)) {
// 参数类型判断
if (!(type instanceof ParameterizedType)) {
throw parameterError(p, rawParameterType.getSimpleName()
+ " must include generic type (e.g., "
+ rawParameterType.getSimpleName()
+ ")");
}
ParameterizedType parameterizedType = (ParameterizedType) type;
// 获取第一个参数的类型
Type iterableType = Utils.getParameterUpperBound(0, parameterizedType);
//获取 输出是String类型的 转化器
Converter, String> converter =
retrofit.stringConverter(iterableType, annotations);
//构建ParameterHandler的内部静态类Field,然后调用iterable()方法 获取一个新的ParameterHandler对象
return new ParameterHandler.Field<>(name, converter, encoded).iterable();
//如果是 数组类型
} else if (rawParameterType.isArray()) {
//装箱操作
Class> arrayComponentType = boxIfPrimitive(rawParameterType.getComponentType());
//获取输出是String的 转化器
Converter, String> converter =
retrofit.stringConverter(arrayComponentType, annotations);
//构建ParameterHandler的内部静态类Field,然后调用array()方法 获取一个新的ParameterHandler对象。
return new ParameterHandler.Field<>(name, converter, encoded).array();
} else {
// 如果既不是集合也不是数组类型,则是普通类型
//获取 输出是String类型转化器
Converter, String> converter =
retrofit.stringConverter(type, annotations);
//构建ParameterHandler的内部静态类Field
return new ParameterHandler.Field<>(name, converter, encoded);
}
//如果@注解 是FieldMap
} else if (annotation instanceof FieldMap) {
//如果不是表单提交则抛异常
if (!isFormEncoded) {
throw parameterError(p, "@FieldMap parameters can only be used with form encoding.");
}
//获取原始类型
Class> rawParameterType = Utils.getRawType(type);
// 如果不是Map接口 ,抛 异常
if (!Map.class.isAssignableFrom(rawParameterType)) {
throw parameterError(p, "@FieldMap parameter type must be Map.");
}
// 获取 类型的 超类
Type mapType = Utils.getSupertype(type, rawParameterType, Map.class);
// 参数类型判断
if (!(mapType instanceof ParameterizedType)) {
throw parameterError(p,
"Map must include generic types (e.g., Map)");
}
ParameterizedType parameterizedType = (ParameterizedType) mapType;
// 获取key的 类型
Type keyType = Utils.getParameterUpperBound(0, parameterizedType);
// key值一定是String
if (String.class != keyType) {
throw parameterError(p, "@FieldMap keys must be of type String: " + keyType);
}
// 获取value的 类型
Type valueType = Utils.getParameterUpperBound(1, parameterizedType);
// 获取 输出类型是String的转化器
Converter, String> valueConverter =
retrofit.stringConverter(valueType, annotations);
//给 gotField 赋值
gotField = true;
//构建ParameterHandler的内部静态类FieldMap。
return new ParameterHandler.FieldMap<>(valueConverter, ((FieldMap) annotation).encoded());
// 如果 是@ Part 注解
} else if (annotation instanceof Part) {
//如果没有使用@isMultipart 注解则抛异常
if (!isMultipart) {
throw parameterError(p, "@Part parameters can only be used with multipart encoding.");
}
//获取 @Part 注解的值
Part part = (Part) annotation;
gotPart = true;
String partName = part.value();
//获取原始类型
Class> rawParameterType = Utils.getRawType(type);
//如果 partName 是空的
if (partName.isEmpty()) {
// 类型是Iterable接口的子类
if (Iterable.class.isAssignableFrom(rawParameterType)) {
// 如果不是参数类型,则抛异常
if (!(type instanceof ParameterizedType)) {
throw parameterError(p, rawParameterType.getSimpleName()
+ " must include generic type (e.g., "
+ rawParameterType.getSimpleName()
+ ")");
}
ParameterizedType parameterizedType = (ParameterizedType) type;
// 获取第一个参数的类型
Type iterableType = Utils.getParameterUpperBound(0, parameterizedType);
//如果原始类型不是MultipartBody.Part的子类,则抛异常
if (!MultipartBody.Part.class.isAssignableFrom(Utils.getRawType(iterableType))) {
throw parameterError(p,
"@Part annotation must supply a name or use MultipartBody.Part parameter type.");
}
// 返回ParameterHandler内部类RawPart.INSTANCE的iterable()方法
return ParameterHandler.RawPart.INSTANCE.iterable();
//如果是数组类型
} else if (rawParameterType.isArray()) {
// 获取类的组件类型的数组
Class> arrayComponentType = rawParameterType.getComponentType();
//如果不是Part类子类,则抛异常
if (!MultipartBody.Part.class.isAssignableFrom(arrayComponentType)) {
throw parameterError(p,
"@Part annotation must supply a name or use MultipartBody.Part parameter type.");
}
// 返回ParameterHandler内部类RawPart.INSTANCE的array()方法
return ParameterHandler.RawPart.INSTANCE.array();
//如果是MultipartBody.Part的子类
} else if
(MultipartBody.Part.class.isAssignableFrom(rawParameterType)) {
return ParameterHandler.RawPart.INSTANCE;
} else {
throw parameterError(p,
"@Part annotation must supply a name or use MultipartBody.Part parameter type.");
}
//partName不为空
} else {
//定义Header
Headers headers =
Headers.of("Content-Disposition", "form-data; name=\"" + partName + "\"",
"Content-Transfer-Encoding", part.encoding());
//如果类型是Iterable的子类
if (Iterable.class.isAssignableFrom(rawParameterType)) {
//参数类型判断
if (!(type instanceof ParameterizedType)) {
throw parameterError(p, rawParameterType.getSimpleName()
+ " must include generic type (e.g., "
+ rawParameterType.getSimpleName()
+ ")");
}
ParameterizedType parameterizedType = (ParameterizedType) type;
//获取 第一个参数的类型
Type iterableType = Utils.getParameterUpperBound(0, parameterizedType);
//使用@Part 注解且注解内部有值,则不能和MultipartBody.Part一起使用,例如:@Part("description") RequestBody description是可以的,@Part MultipartBody.Part file也是可以的,但是@Partt("file") MultipartBody.Part file 是不可以的。
if (MultipartBody.Part.class.isAssignableFrom(Utils.getRawType(iterableType))) {
throw parameterError(p, "@Part parameters using the MultipartBody.Part must not "
+ "include a part name in the annotation.");
}
//获取输出是RequestBody的转化器
Converter, RequestBody> converter =
retrofit.requestBodyConverter(iterableType, annotations, methodAnnotations);
// 返回ParameterHandler内部类Part的实例,然后调用的iterable()方法返回一个ParameterHandler对象
return new ParameterHandler.Part<>(headers, converter).iterable();
//如果类型是数组类型
} else if (rawParameterType.isArray()) {
//获取数组类型的类型
Class> arrayComponentType = boxIfPrimitive(rawParameterType.getComponentType());
//同理不能使用MultipartBody.Part.和有值的@Part 注解
if (MultipartBody.Part.class.isAssignableFrom(arrayComponentType)) {
throw parameterError(p, "@Part parameters using the MultipartBody.Part must not "
+ "include a part name in the annotation.");
}
//获取输出是RequestBody的转化器
Converter, RequestBody> converter =
retrofit.requestBodyConverter(arrayComponentType, annotations, methodAnnotations);
// 返回ParameterHandler内部类Part的实例,然后调用的array()方法返回一个ParameterHandler对象
return new ParameterHandler.Part<>(headers, converter).array();
//如果既不是数组也是Iterable,但是普通类型也不能让@Part的值有值且同时使用MultipartBody.Part
} else if (MultipartBody.Part.class.isAssignableFrom(rawParameterType)) {
throw parameterError(p, "@Part parameters using the MultipartBody.Part must not "
+ "include a part name in the annotation.");
} else {
//不是MultipartBody.Par类型,则获取输出是RequestBody的转化器
Converter, RequestBody> converter =
retrofit.requestBodyConverter(type, annotations, methodAnnotations);
//构建ParameterHandler的静态内部类Part
return new ParameterHandler.Part<>(headers, converter);
}
}
//如果是@PartMap 注解
} else if (annotation instanceof PartMap) {
//没有使用@isMultipart 抛异常。
if (!isMultipart) {
throw parameterError(p, "@PartMap parameters can only be used with multipart encoding.");
}
//给gotPart赋值
gotPart = true;
//获取原始类型
Class> rawParameterType = Utils.getRawType(type);
//如果不是Map的类型,则抛异常
if (!Map.class.isAssignableFrom(rawParameterType)) {
throw parameterError(p, "@PartMap parameter type must be Map.");
}
//获取类型的超类
Type mapType = Utils.getSupertype(type, rawParameterType, Map.class);
//参数类型判断
if (!(mapType instanceof ParameterizedType)) {
throw parameterError(p, "Map must include generic types (e.g., Map)");
}
ParameterizedType parameterizedType = (ParameterizedType) mapType;
//获取key的类型
Type keyType = Utils.getParameterUpperBound(0, parameterizedType);
//排除key不是String的类型
if (String.class != keyType) {
throw parameterError(p, "@PartMap keys must be of type String: " + keyType);
}
//获取value的类型
Type valueType = Utils.getParameterUpperBound(1, parameterizedType);
//@PartMap 不能和 @MultipartBody.Part 一起使用
if (MultipartBody.Part.class.isAssignableFrom(Utils.getRawType(valueType))) {
throw parameterError(p, "@PartMap values cannot be MultipartBody.Part. "
+ "Use @Part List or a different value type instead.");
}
//获取输出是RequestBody的 转换器
Converter, RequestBody> valueConverter =
retrofit.requestBodyConverter(valueType, annotations, methodAnnotations);
PartMap partMap = (PartMap) annotation;
//构建ParameterHandler的内部静态类PartMap。
return new ParameterHandler.PartMap<>(valueConverter, partMap.encoding());
// 如果注解是 @Body
} else if (annotation instanceof Body) {
//@Body 注解是不能和 @FormEncoded @Multipart 注解一起使用,如果一起使用抛异常
if (isFormEncoded || isMultipart) {
throw parameterError(p,
"@Body parameters cannot be used with form or multi-part encoding.");
}
//@Body 只能使用一次
if (gotBody) {
throw parameterError(p, "Multiple @Body method annotations found.");
}
// 输出是RequestBody的 转化器
Converter, RequestBody> converter;
try {
converter = retrofit.requestBodyConverter(type, annotations, methodAnnotations);
} catch (RuntimeException e) {
// Wide exception range because factories are user code.
throw parameterError(e, p, "Unable to create @Body converter for %s", type);
}
//给gotBody赋值为true
gotBody = true;
//构建ParameterHandler的内部静态类Body。
return new ParameterHandler.Body<>(converter);
}
//如果上面都处理,则说明使用了一个非Retrofit的的注解,返回null
return null; // Not a Retrofit annotation.
}
内容如下:
主要是根据具体的参数注解类型,然后具体处理。
补充一个问题:
Path注解与Url注解不能同时使用,否则会抛出paramterError错误,其实原因有很好理解,Path注解用于替换url路径中参数,这就要求在使用path注解时,必须赢存在请求路径,不然没法替换路径中指定的参数,而Url注解是在参数中指定的请求路径的,这个时候指定请求路径已经晚了,path注解找不到请求路径,更别提更换请求路径中的参数了。
3.2.10、 Builder的方法validatePathName解析
看方法名字 是检验路径名字
private void validatePathName(int p, String name) {
if (!PARAM_NAME_REGEX.matcher(name).matches()) {
throw parameterError(p, "@Path parameter name must match %s. Found: %s",
PARAM_URL_REGEX.pattern(), name);
}
// Verify URL replacement name is actually present in the URL path.
if (!relativeUrlParamNames.contains(name)) {
throw parameterError(p, "URL \"%s\" does not contain \"{%s}\".", relativeUrl, name);
}
}
根据正则表达式,来判断url是否正确
3.2.11、 Builder的方法createResponseConverter解析
通过方法名,我们猜是创建响应转化器
private Converter createResponseConverter() {
//获取方法的注解
Annotation[] annotations = method.getAnnotations();
try {
//调用retrofit的responseBodyConverter()方法来获取一个输入是ResponseBody的转化器
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的responseBodyConverter()来获取输入是ResponseBody的转化器,关于Retrofit我下面再介绍
3.2.12、 Builder的方法methodError解析
主要就是输出错误信息
private RuntimeException methodError(String message, Object... args) {
return methodError(null, message, args);
}
private RuntimeException methodError(Throwable cause, String message, Object... args) {
message = String.format(message, args);
return new IllegalArgumentException(message
+ "\n for method "
+ method.getDeclaringClass().getSimpleName()
+ "."
+ method.getName(), cause);
}
3.2.13、 Builder的方法parameterError解析
输出参数错误
private RuntimeException parameterError(
Throwable cause, int p, String message, Object... args) {
return methodError(cause, message + " (parameter #" + (p + 1) + ")", args);
}
private RuntimeException parameterError(int p, String message, Object... args) {
return methodError(message + " (parameter #" + (p + 1) + ")", args);
}
至此,ServiceMethod类已经讲解完毕了,大家对这个类熟悉了吗?
ok,我们来看最后一个类Retrofit类
三、Retrofit
(一) 类注释
老规矩先来认识下这个类,首先看这个类的注释
Retrofit adapts a Java interface to HTTP calls by using annotations on the declared methods to define how requests are made. Create instances using {@linkplain Builder the builder} and pass your interface to {@link #create} to generate an implementation.
翻译一下:
Retroft把一个java接口的抽象方法 适配/转化 成一个HTTP的请求,它内部是使用解析接口内部的抽象方法上的注解来定义如何去发起请求。通过Builder可以创建Retroft的实例,通过调用create()方法来创建一个接口的具体实现类。
(二) 类代码解析
由于这个类的代码比价长,我就不全部粘贴,等用到时候再一一粘贴
1、变量解析
那我们来看下他对应的变量,内容不多也比较简单,比较复杂的,我直接在上注释了。
//serviceMethod对象集合的缓存,用于重用,由于里面用到了反射,大家知道反射比较消耗性能,所以为了避免重复反射,节约性能,使用缓存,保证只反射一次。
private final Map> serviceMethodCache = new ConcurrentHashMap<>();
final okhttp3.Call.Factory callFactory;
final HttpUrl baseUrl;
//转化工厂 集合
final List converterFactories;
// 请求适配工厂 集合
final List adapterFactories;
// 回调的线程池
final Executor callbackExecutor;
//如果为true,程序是在做一个预处理的操作,只是提前创建了一些MethodHandler对象在缓存中。
final boolean validateEagerly;
- 以上所有变量都是final的,所以构造的时候赋值了,不会二次赋值
- 这里提一下validateEagerly变量,他是和eagerlyValidateMethods对应的,后面再详细讲解。
2、构造函数解析
Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
List converterFactories, List adapterFactories,
Executor callbackExecutor, boolean validateEagerly) {
this.callFactory = callFactory;
this.baseUrl = baseUrl;
this.converterFactories = unmodifiableList(converterFactories); // Defensive copy at call site.
this.adapterFactories = unmodifiableList(adapterFactories); // Defensive copy at call site.
this.callbackExecutor = callbackExecutor;
this.validateEagerly = validateEagerly;
}
- 构造函数很简单,就是赋值
- 里面调用了Collections.unmodifiableList的方法检查是否是List,注意他的导包"import static java.util.Collections.unmodifiableList",值得我们学习。
- 构造既不是public也不是private,所以不能在包外直接new,所以我们要通过Builder来创建Retrofit对象
3、相关方法解析
由于create比较关键,我们最后解析
3.1、eagerlyValidateMethods方法解析
private void eagerlyValidateMethods(Class> service) {
//获取平台对象,安卓对象是Platform.Android
Platform platform = Platform.get();
//获取service类的所有方法,然后遍历它的所有方法
for (Method method : service.getDeclaredMethods()) {
//由于Platform.Android没有实现isDefaultMethod方法,所以默认返回false
if (!platform.isDefaultMethod(method)) {
//调用loadServiceMethod()方法导入方法
loadServiceMethod(method);
}
}
}
具体流程如下:
- 1、收取平台对象
- 2、获取所有类的所有方法,这里补充一个知识点:getDeclaredMethods()方法返回的是类或接口声明的所有方法,包括public、protect、private、默认的方法,但不包括它继承的方法。当然也包括它所有实现接口的方法。getMethods()返回的是某个类的所有public的方法,包括其继承类的public方法,也包括实现接口的方法。
- 3、遍历这类的所有方法
- 4、由于Platform.Android没有重写isDefaultMethod(),所以platform.isDefaultMethod(method)默认返回false,Platform.Java8是重写了这个方法的,大家有兴趣的话可以去研究下。
- 5、调用loadServiceMethod()方法
那么就让我们研究下loadServiceMethod这个方法
3.2、loadServiceMethod方法解析
ServiceMethod, ?> loadServiceMethod(Method method) {
//从缓冲中取出
ServiceMethod, ?> result = serviceMethodCache.get(method);
//如果缓存中有,直接取出
if (result != null) return result;
//如果缓存中没有,加上同步锁
synchronized (serviceMethodCache) {
//加上锁后,为了保证实时性,再去一次
result = serviceMethodCache.get(method);
//如果还没有
if (result == null) {
//直接构建一个ServiceMethod.Builder对象,然后调用ServiceMethod.Builder的builer方法构建一个ServiceMethod对象关于build方法刚刚讲过哦
result = new ServiceMethod.Builder<>(this, method).build();
把这个ServiceMethod 对象放入缓存中
serviceMethodCache.put(method, result);
}
}
//返回这个ServiceMethod 对象
return result;
}
其实看上面方法,其实就是一个一级缓存。先判断缓存中有没有,如果缓存中有,则直接返回,如果缓存没有,则获取一个,并添加到缓存中。
3.3、callFactory()、baseUrl()、callAdapterFactories() 、converterFactories()方法解析由于这四个方法比较简单,其实就是get方法获对应的属性,没什么好说的,就简单贴下代码,大家看下就好。
/**
* The factory used to create {@linkplain okhttp3.Call OkHttp calls} for sending a HTTP requests.
* Typically an instance of {@link OkHttpClient}.
*/
public okhttp3.Call.Factory callFactory() {
return callFactory;
}
/** The API base URL. */
public HttpUrl baseUrl() {
return baseUrl;
}
/**
* Returns a list of the factories tried when creating a
* {@linkplain #callAdapter(Type, Annotation[])} call adapter}.
*/
public List callAdapterFactories() {
return adapterFactories;
}
/**
* Returns a list of the factories tried when creating a
* {@linkplain #requestBodyConverter(Type, Annotation[], Annotation[]) request body converter}, a
* {@linkplain #responseBodyConverter(Type, Annotation[]) response body converter}, or a
* {@linkplain #stringConverter(Type, Annotation[]) string converter}.
*/
public List converterFactories() {
return converterFactories;
}
3.4、callAdapter() 方法解析
在上面ServiceMethod类中可是调用过这个方法的,大家还记得在哪里调用吗?是在ServiceMethod类中createCallAdapter()方法里面最后return的时候调用了,那我们来看下源码
/**
* Returns the {@link CallAdapter} for {@code returnType} from the available {@linkplain
* #callAdapterFactories() factories}.
*
* @throws IllegalArgumentException if no call adapter available for {@code type}.
*/
public CallAdapter, ?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
通过方法注释我们知道
从callAdapterFactories里面找到合适的CallAdapter,这个CallAdapter的返回值类型是returnType
大家看代码,其实内部调用的是nextCallAdapter()方法,那我们就来看下nextCallAdapter()方法
3.5、nextCallAdapter()方法解析
/**
* Returns the {@link CallAdapter} for {@code returnType} from the available {@linkplain
* #callAdapterFactories() factories} except {@code skipPast}.
*
* @throws IllegalArgumentException if no call adapter available for {@code type}.
*/
public CallAdapter, ?> nextCallAdapter(CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
//非空判断
checkNotNull(returnType, "returnType == null");
checkNotNull(annotations, "annotations == null");
//获取skipPast的位置,skpiPost属于被抛弃的一方
int start = adapterFactories.indexOf(skipPast) + 1;
//如果skipPast是null,则start=-1,如果skipPast存在则从skipPast的下一个位置开始遍历
for (int i = start, count = adapterFactories.size(); i < count; i++) {
//通过CallAdapter.Factory的get方法来获取对应的CallAdapter
CallAdapter, ?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
//如果adapter不为null,则返回adapter
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(adapterFactories.get(i).getClass().getName());
}
builder.append('\n');
}
builder.append(" Tried:");
for (int i = start, count = adapterFactories.size(); i < count; i++) {
builder.append("\n * ").append(adapterFactories.get(i).getClass().getName());
}
throw new IllegalArgumentException(builder.toString());
}
先来看下方法的注释:
除了skipPast(这个对象外),从callAdapterFactories里面再找一个返回类型是returnType的CallAdapter 对象
内容很简单,主要是遍历callAdapterFactories里面,找到合适的CallAdapter,如果没有则抛出异常。
3.6、requestBodyConverter()方法解析
/**
* Returns a {@link Converter} for {@code type} to {@link RequestBody} from the available
* {@linkplain #converterFactories() factories}.
*
* @throws IllegalArgumentException if no converter available for {@code type}.
*/
public Converter requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations) {
return nextRequestBodyConverter(null, type, parameterAnnotations, methodAnnotations);
}
从converterFactories里面找到一个合适的Converter,这个Converter的输出类型是RequestBody。
其实内部调用的是nextRequestBodyConverter,那我们看下这个nextRequestBodyConverter接口
3.7、nextRequestBodyConverter()方法解析
/**
* Returns a {@link Converter} for {@code type} to {@link RequestBody} from the available
* {@linkplain #converterFactories() factories} except {@code skipPast}.
*
* @throws IllegalArgumentException if no converter available for {@code type}.
*/
public Converter nextRequestBodyConverter(Converter.Factory skipPast,
Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations) {
//非空检查
checkNotNull(type, "type == null");
checkNotNull(parameterAnnotations, "parameterAnnotations == null");
checkNotNull(methodAnnotations, "methodAnnotations == null");
//获取被放弃的skipPast对象的位置,然后加1
int start = converterFactories.indexOf(skipPast) + 1;
//遍历converterFactories
for (int i = start, count = converterFactories.size(); i < count; i++) {
//获取对应的 Converter.Factory对象,然后调用requestBodyConverter()方法,
Converter.Factory factory = converterFactories.get(i);
Converter, RequestBody> converter =
factory.requestBodyConverter(type, parameterAnnotations, methodAnnotations, this);
//由于requestBodyConverter()默认是返回null,所以只有重写过才会不为null
if (converter != null) {
//noinspection unchecked
return (Converter) 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());
}
先来说下方法的注释
除了skipPast(这个对象外),从converterFactories里面再找输出类型是RequestBody的converter 对象
内容很简单
有点类似于nextCallAdapter(),主要是遍历converterFactories,找到合适的converter,如果没有则抛出异常。
3.8、responseBodyConverter()方法解析
/**
* Returns a {@link Converter} for {@link ResponseBody} to {@code type} from the available
* {@linkplain #converterFactories() factories}.
*
* @throws IllegalArgumentException if no converter available for {@code type}.
*/
public Converter responseBodyConverter(Type type, Annotation[] annotations) {
return nextResponseBodyConverter(null, type, annotations);
}
先看下方法的注释
从converterFactories里面找到一个合适的Converter,这个Converter的输如类型是ResponseBody。
其实内部调用时的nextResponseBodyConverter(),那我们来看下nextResponseBodyConverter()的具体实现。
3.9、nextResponseBodyConverter()方法解析
/**
* Returns a {@link Converter} for {@link ResponseBody} to {@code type} from the available
* {@linkplain #converterFactories() factories} except {@code skipPast}.
*
* @throws IllegalArgumentException if no converter available for {@code type}.
*/
public Converter nextResponseBodyConverter(Converter.Factory skipPast,
Type type, Annotation[] annotations) {
//非空判断
checkNotNull(type, "type == null");
checkNotNull(annotations, "annotations == null");
//获取被放弃的skipPast的位置,如果是null则是-1
int start = converterFactories.indexOf(skipPast) + 1;
//遍历converterFactories
for (int i = start, count = converterFactories.size(); i < count; i++) {
//通过responseBodyConverter()来获取一个输入是ResponseBody的Converter
Converter converter =
converterFactories.get(i).responseBodyConverter(type, annotations, this);
//如果Converter不为null,则说明找到了
if (converter != null) {
//noinspection unchecked
return (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());
}
先看下注释
除了skipPast(这个对象外),从converterFactories里面再找一个输入类型是ResponseBody的Converter 对象
通过阅读源码,我们发现:
有点类似于nextRequestBodyConverter(),主要是遍历converterFactories,找到合适的converter,如果没有则抛出异常。
3.10、stringConverter()方法解析
/**
* Returns a {@link Converter} for {@code type} to {@link String} from the available
* {@linkplain #converterFactories() factories}.
*/
public Converter stringConverter(Type type, Annotation[] annotations) {
//非空判断
checkNotNull(type, "type == null");
checkNotNull(annotations, "annotations == null");
//获取对应的 Converter.Factory对象
for (int i = 0, count = converterFactories.size(); i < count; i++) {
//然后调用stringConverter()方法获取对应的Converter对象
Converter, String> converter =
converterFactories.get(i).stringConverter(type, annotations, this);
//非空判断,因为如果找不到,则返回null
if (converter != null) {
//noinspection unchecked
return (Converter) converter;
}
}
// 如果遍历了,还是没有合适的,调用默认的转换器的toString()方法,默认的转换器是BuiltInConverters
// Nothing matched. Resort to default converter which just calls toString().
//noinspection unchecked
return (Converter) BuiltInConverters.ToStringConverter.INSTANCE;
}
先来看下方法的注释,翻译一下:
从converterFactories里面找到一个合适的Converter,这个Converter的输出类型是RequestBody。
实际内容也很简单,遍历converterFactories。获取Converter.Factory对象,调用这个对象的stringConverter()来获取Converter对象,如果Converter不为空,则证明取到了,如果没有取到,则调用默认的转化器来转化。
3.11、callbackExecutor()方法解析
/**
* The executor used for {@link Callback} methods on a {@link Call}. This may be {@code null},
* in which case callbacks should be made synchronously on the background thread.
*/
public Executor callbackExecutor() {
return callbackExecutor;
}
先翻译一下
这个线程池被用来执行一个请求的回调,在这种情况下,回调应该在后台线程上同步进行。
其实就会返回回调的线程池
3.12、newBuilder()方法解析
代码很简单,就是new一个Builder对象并返回
public Builder newBuilder() {
return new Builder(this);
}
(三) 静态内部类Builder解析
1、老规矩先来看下类的注释
/**
* Build a new {@link Retrofit}.
*
* Calling {@link #baseUrl} is required before calling {@link #build()}. All other methods
* are optional.
*/
翻译一下:
通过调用一个build()方法来构建一个Retrofit对象,在build()之前需要调用baseUrl()方法,所有其他方法都是可选的。
2、看下变量
变量不多,我直接上注释了
//平台
private final Platform platform;
//okhttp3的callFactory
private okhttp3.Call.Factory callFactory;
//HttpUrl
private HttpUrl baseUrl;
//converterFactories集合
private final List converterFactories = new ArrayList<>();
//adapterFactories 集合
private final List adapterFactories = new ArrayList<>();
//回调线程池
private Executor callbackExecutor;
//是否需要提前检查的布尔变量
private boolean validateEagerly;
通过上述代码我们可以得出以下信息
- 1、converterFactories和adapterFactories一定是不为null的
- 2、platform是final的,初始化的时候一定要赋值的
3、构造函数
Builder有三个构造函数,一个是无参的public,两个是包内的,所以,外部调用一定是new无参的构造函数
Builder(Platform platform) {
this.platform = platform;
// 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());
}
public Builder() {
this(Platform.get());
}
Builder(Retrofit retrofit) {
platform = Platform.get();
callFactory = retrofit.callFactory;
baseUrl = retrofit.baseUrl;
converterFactories.addAll(retrofit.converterFactories);
adapterFactories.addAll(retrofit.adapterFactories);
// Remove the default, platform-aware call adapter added by build().
adapterFactories.remove(adapterFactories.size() - 1);
callbackExecutor = retrofit.callbackExecutor;
validateEagerly = retrofit.validateEagerly;
}
- 1、无参数的构造函数其实内部调用的是入参是Platform的构造函数,Platform.get()方法我们前面已经说过了,返回的是Android对象
- 2、入参是platform的构造函数,内部add了一个BuiltInConverters对象,可见converterFactories至少是一个转化器的。
- 3、入参的是Retrofit的构造函数,其实就是把Retrofit的属性赋值给Builder
4、相关方法解析
4.1、client方法和callFactory
/**
* The HTTP client used for requests.
*
* This is a convenience method for calling {@link #callFactory}.
* 通过callFactory作为客户端,来发起HTTP请求是非常便捷的。
*/
public Builder client(OkHttpClient client) {
return callFactory(checkNotNull(client, "client == null"));
}
/**
* Specify a custom call factory for creating {@link Call} instances.
*
* Note: Calling {@link #client} automatically sets this value.
* 通过自定义的call factory 来创建一个请求(Call)的实例,调用client会自动设置
*/
public Builder callFactory(okhttp3.Call.Factory factory) {
this.callFactory = checkNotNull(factory, "factory == null");
return this;
}
通过上面我们可知
- client内部调用的callFactory方法
- 这两个方法表明,Retrofit底层是使用okHttp,而且是强关联。
- PS:第一次看代码的哥们可能会有疑惑,这里补充下OkHttpClient是okhttp3.Call.Factory的实现类。
4.2、baseUrl方法
Builder有两个baseUrl,只不过是入参不同而已,让我们来看下源码
/**
* Set the API base URL.
*
* @see #baseUrl(HttpUrl)
*/
public Builder baseUrl(String baseUrl) {
checkNotNull(baseUrl, "baseUrl == null");
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();
if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
}
this.baseUrl = baseUrl;
return this;
}
- 主要是设置基本的url,一般是请求的url的前缀
- 受篇幅限制,我这边没有粘贴注释,不过注释非常不错,我建议大家还是去看看,里面主要讲解拼接的注意事件。
4.3、addConverterFactory()和addCallAdapterFactory方法
/** Add converter factory for serialization and deserialization of objects. */
public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
/**
* Add a call adapter factory for supporting service method return types other than {@link
* Call}.
*/
public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
adapterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
addConverterFactory()和addCallAdapterFactory方法比较简单,就是向对应的集合添加元素而已
4.4、callbackExecutor()和validateEagerly方法
/**
* The executor on which {@link Callback} methods are invoked when returning {@link Call} from
* your service method.
*
* Note: {@code executor} is not used for {@linkplain #addCallAdapterFactory custom method
* return types}.
*/
public Builder callbackExecutor(Executor executor) {
this.callbackExecutor = checkNotNull(executor, "executor == null");
return this;
}
/**
* When calling {@link #create} on the resulting {@link Retrofit} instance, eagerly validate
* the configuration of all methods in the supplied interface.
*/
public Builder validateEagerly(boolean validateEagerly) {
this.validateEagerly = validateEagerly;
return this;
}
这两个方法也比较简单,就是给两个变量赋值
4.5、build()方法
/**
* Create the {@link Retrofit} instance using the configured values.
*
* Note: If neither {@link #client} nor {@link #callFactory} is called a default {@link
* OkHttpClient} will be created and used.
*/
public Retrofit build() {
//如果没有配置过baseUrl,则抛异常
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
//获取callFactory
okhttp3.Call.Factory callFactory = this.callFactory;
//如果为null,则没有调用过client()和callFactory()方法
if (callFactory == null) {
//创建一个OkHttpClient对象,作为默认的callFactory
callFactory = new OkHttpClient();
}
//获取回调的线程池
Executor callbackExecutor = this.callbackExecutor;
// 如果callbackExecutor为null,则没有设置过回调线程池,
if (callbackExecutor == null) {
//获取平台默认的线程池,其实就是主线程
callbackExecutor = platform.defaultCallbackExecutor();
}
// Make a defensive copy of the adapters and add the default Call adapter.
// 给adapterFactories赋值
List adapterFactories = new ArrayList<>(this.adapterFactories);
//添加一个默认的callAdapter,其实是DefaultCallAdapterFactory
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
// Make a defensive copy of the converters.
// 设置converterFactories,它默认是含有BuiltInConverters对象的
List converterFactories = new ArrayList<>(this.converterFactories);
//构建一个Retrofit对象
return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
callbackExecutor, validateEagerly);
}
先看下注释
通知使用配置过的值来创建Retrofit对象,如果没有调用client()和callFactory()方法,那么将创建并使用默认的OkHttpClient。
代码很简单,就是初始化属性,这里重点说下,如果没有设置回调线程池,则默认是主线程,如果没有配置转化器,则默认使用BuiltInConverters,如果没配置callAdapter,则默认使用DefaultCallAdapterFactory。
(四) create()方法解析
这个方法很重要,由于受到篇幅限制,我就不粘贴注释的了,我们先来看下源码
@SuppressWarnings("unchecked") // Single-interface proxy creation guarded by parameter safety.
public T create(final Class service) {
Utils.validateServiceInterface(service);
if (validateEagerly) {
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, Object[] args)
throws Throwable {
// If the method is a method from Object then defer to normal invocation.
//如果定义方法的类的类型是Object,或者说,是Object类的方法,则直接执行invoke调用
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
// Android平台没有重写这个方法,所以默认是false
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
//调用loadServiceMethod获取一个ServiceMethod对象,其内部是一个一级缓存,内存中有直接取内存中的,内存中没有构建一个ServiceMethod,放入到缓存中。
ServiceMethod
通过源码我们知道,这方法内部的流程如下:
- 检查 接口类,判断是否是接口,判断是否继承其他接口
- 做是否需要预加载
- 调用动态代理获取一个类的对象
然后我们看下InvocationHandler里面的invoke()方法里面的实现流程
- 先判断这个方法是不是Object的方法,如果是直接接调用invoke
- 根据平台的特性,决定是否调用invokeDefaultMethod()方法
- 通过调用loadServiceMethod()方法载入一个ServiceMethod对象。
- 用ServiceMethod来构建一个OkHttpCall。
- 最后调用serviceMethod对象的callAdapter对象的adapt方法
最后翻译了一下这个方法对应的注释,受篇幅限制,我就不粘贴源码了,直接上我们翻译后的内容了
创建一个由服务器定义的API接口的具体实现。如果在抽象接口的方法上通过添加注解来实现设置定义请求方式,而相对路径的url是根据这个请求方式来的。请求方式有@link retrofit2.http.GET 代表GET请求,@link retrofit2.http.PUT 代表PUT请求,@retrofit2.http.POST,代表POST请求,@retrofit2.http.PATCH 代表PATCH请求,@retrofit2.http.HEAD 代表HEAD请求,
@retrofit2.http.DELETE 代表DELETE请求, @retrofit2.http.OPTIONS 代表OPTIONS请求,通过使用@HTTP,你也可以自定义HTTP请求方式。如果你想动态设置url,第一个入参需要使用@Url 注解来实现。可以在方法参数里面使用@Path注解,是实现替换Url部分内容,被替换的部分需要用大括号“{}”括起来,例如"{foo}"。如果想在URL上添加查询字段,就要使用@Query 注解。用@ Body 来表示一个请求体。一个对象的实例将会被Converter.Factory的实例转化为网络请求。一个RequestBody也可以作为原始数据而直接使用。方法注解和参数注解支持如下的格式:通过@FormUrlEncoded,代表表单提交,由@Field注解 代表表单数据。@multipart 代表多部分,在入参上使用注解@Part表示每一部分的具体数据。通过在方法上添加@Header 和@Header来添加请求头的数据。默认情况下,这个方法返回一个代表HTTP请求的Call对象,里面的泛型是响应体的类型,由 Converter.Factory对象负责转化,也可以用ResponseBody代表原始数据,当然你不关心请求体,也可以设置Void。