先来看Retrofit的基本使用,先建一个接口列表
interface APIServices {
@GET("/wxarticle/chapters/json")
fun listPublic(): Call<PublicBean>
}
这里来写请求的方法,注,这里没有使用Rxjava,所以直接返回Call对象,然后使用
var okHttpClient = OkHttpClient.Builder().build()
var retrofit = Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("https://wanandroid.com/")
.client(okHttpClient)
.build()
var apiServices = retrofit.create(APIServices::class.java)
var call = apiServices.listPublic()
call.enqueue(object : retrofit2.Callback<PublicBean> {
override fun onFailure(call: retrofit2.Call<PublicBean>, t: Throwable) {
}
override fun onResponse(
call: retrofit2.Call<PublicBean>,
response: retrofit2.Response<PublicBean>
) {
var publicBean = response.body()
Log.e("TAG", "----->$publicBean")
}
})
简单的使用就这样,来看分析,
//创建OkHttpClient,使用自己的OkHttpClient
var okHttpClient = OkHttpClient.Builder().build()
//创建Retrofit对象
var retrofit = Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("https://wanandroid.com/")
.client(okHttpClient)
.build()
就是通过build来创建Retrofit对象,没什么好说的,接下来看retrofit.create(APIServices::class.java)干了什么
//注意,这里返回的是T对象,也就是我们传过来的class,这里就是APIServices对象
public <T> T create(final Class<T> service) {
//判断service是否为接口,不是就抛出异常
Utils.validateServiceInterface(service);
//判断是否提前加载方法,默认为false
if (validateEagerly) {
eagerlyValidateMethods(service);
}
//通过动态代理创建APIServices对象,返回
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();
private final Object[] emptyArgs = new Object[0];
@Override public @Nullable Object invoke(Object proxy, Method method,
@Nullable Object[] args) throws Throwable {
// If the method is a method from Object then defer to normal invocation.
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}
});
}
到这里,通过动态代理创建了一个APIServices的实例,有关动态代理,请自行了解,到这里就是到retrofit.create(APIServices::class.java)就是通过动态代理返回了一个APIServices对象,继续往下看
//通过动态代理,返回APIServices对象
var apiServices = retrofit.create(APIServices::class.java)
//调用接口
var listPublic = apiServices.listPublic()
//...
当调用apiServices.listPublic()方法时,会走到动态代理中的InvocationHandler里面的invoke方法中,并且apiServices.listPublic()的返回值就是invoke方法的返回值;所以我这里的listPublic是Call<PublicBean>类型,也就是invoke()返回的对象,看invoke()返回什么
public <T> T create(final Class<T> 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();
private final Object[] emptyArgs = new Object[0];
//每次调用对应的接口方法时,都会走来这里,并且其返回值就是该方法的返回值
@Override public @Nullable Object invoke(Object proxy, Method method,
@Nullable Object[] args) throws Throwable {
// 如果为常用的,则直接返回正常的调用方式
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
//默认返回false
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
//所以我我们会走来到这里
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}
});
}
所以当调用apiServices.listPublic()方法时,就会走到loadServiceMethod(method).invoke(args != null ? args : emptyArgs);这里,就相当于这样
var listPublic = apiServices.listPublic()
var listPublic = loadServiceMethod(method).invoke(args != null ? args : emptyArgs)
listPublic就是这样返回的,先看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
result = ServiceMethod.parseAnnotations(this, method);
//保存到缓存中
serviceMethodCache.put(method, result);
}
}
return result;
}
这个方法就是一个缓存机制,继续看是如何生成ServiceMethod对象的
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
//解析注解,并生成RequestFactory对抗
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);
}
//如果返回值为null,抛出异常
if (returnType == void.class) {
throw methodError(method, "Service methods cannot return void.");
}
//生成ServiceMethod并返回
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
先来看RequestFactory.parseAnnotations(retrofit, method);是如何解析注解的
static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
//又是builder返回对象
return new Builder(retrofit, method).build();
}
RequestFactory build() {
//循环注解内容
for (Annotation annotation : methodAnnotations) {
//解析注解
parseMethodAnnotation(annotation);
}
//解析注解之后,如果httpMethod为null,抛异常
if (httpMethod == null) {
throw methodError(method, "HTTP method annotation is required (e.g., @GET, @POST, etc.).");
}
//检验
if (!hasBody) {
if (isMultipart) {
throw methodError(method,
"Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
}
if (isFormEncoded) {
throw methodError(method, "FormUrlEncoded can only be specified on HTTP methods with "
+ "request body (e.g., @POST).");
}
}
//获取方法参数个数
int parameterCount = parameterAnnotationsArray.length;
//创建参数数组
parameterHandlers = new ParameterHandler<?>[parameterCount];
//解析参数
for (int p = 0, lastParameter = parameterCount - 1; p < parameterCount; p++) {
parameterHandlers[p] =
parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p], p == lastParameter);
}
//检验null
if (relativeUrl == null && !gotUrl) {
throw methodError(method, "Missing either @%s URL or @Url parameter.", httpMethod);
}
if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
throw methodError(method, "Non-body HTTP method cannot contain @Body.");
}
if (isFormEncoded && !gotField) {
throw methodError(method, "Form-encoded method must contain at least one @Field.");
}
if (isMultipart && !gotPart) {
throw methodError(method, "Multipart method must contain at least one @Part.");
}
//创建RequestFactory,返回
return new RequestFactory(this);
}
所以上面中,就两个方法比较重要
- parseMethodAnnotation()解析注解方法
- parseParameter()解析参数方法
先来看第一个
private void parseMethodAnnotation(Annotation annotation) {
//判断注解类型,GET、POST等
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) {
//解析@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) {
//如果是Multipart类型
if (isFormEncoded) {
throw methodError(method, "Only one encoding annotation is allowed.");
}
isMultipart = true;
} else if (annotation instanceof FormUrlEncoded) {
//如果为FormUrlEncoded
if (isMultipart) {
throw methodError(method, "Only one encoding annotation is allowed.");
}
isFormEncoded = true;
}
}
上面有两个方法,一个解析GET、POST注解的方法parseHttpMethodAndPath()和解析Headers注解的方法parseHeaders()先来看第一个
private void parseHttpMethodAndPath(String httpMethod, String value, boolean hasBody) {
//验证httpMethod,如果不为null,说明已经解析过,说明重复设置了,抛异常
if (this.httpMethod != null) {
throw methodError(method, "Only one HTTP method is allowed. Found: %s and %s.",
this.httpMethod, httpMethod);
}
//设置请求方法
this.httpMethod = httpMethod;
//设置是否有Body
this.hasBody = hasBody;
//判断注解中的值
if (value.isEmpty()) {
return;
}
//判断是否包含?符号
int question = value.indexOf('?');
if (question != -1 && question < value.length() - 1) {
// Ensure the query string does not have any named parameters.
String queryParams = value.substring(question + 1);
Matcher queryParamMatcher = PARAM_URL_REGEX.matcher(queryParams);
if (queryParamMatcher.find()) {
throw methodError(method, "URL query string \"%s\" must not have replace block. "
+ "For dynamic query parameters use @Query.", queryParams);
}
}
//设置url
this.relativeUrl = value;
//设置url参数
this.relativeUrlParamNames = parsePathParameters(value);
}
这个方法就是设置一些参数,接下来看parseHeaders()方法
private Headers parseHeaders(String[] headers) {
Headers.Builder builder = new Headers.Builder();
//循环heads
for (String header : headers) {
//判断是否包含:
int colon = header.indexOf(':');
//不包含,说明设置错误
if (colon == -1 || colon == 0 || colon == header.length() - 1) {
throw methodError(method,
"@Headers value must be in the form \"Name: Value\". Found: \"%s\"", header);
}
//获取头名称
String headerName = header.substring(0, colon);
//获取头内容
String headerValue = header.substring(colon + 1).trim();
//如果为Content-Type
if ("Content-Type".equalsIgnoreCase(headerName)) {
try {
//重新设置contentType的值
contentType = MediaType.get(headerValue);
} catch (IllegalArgumentException e) {
throw methodError(method, e, "Malformed content type: %s", headerValue);
}
} else {
//否则,直接添加到Headers中
builder.add(headerName, headerValue);
}
}
//返回
return builder.build();
}
就是解析一些头信息,接下来看parseParameter()解析参数的方法
private @Nullable ParameterHandler<?> parseParameter(
int p, Type parameterType, @Nullable Annotation[] annotations, boolean allowContinuation) {
ParameterHandler<?> result = null;
if (annotations != null) {
//循环参数的注解
for (Annotation annotation : annotations) {
//解析参数注解
ParameterHandler<?> annotationAction =
parseParameterAnnotation(p, parameterType, annotations, annotation);
//为null,继续循环下一个
if (annotationAction == null) {
continue;
}
//如果已经赋值,抛异常
if (result != null) {
throw parameterError(method, p,
"Multiple Retrofit annotations found, only one allowed.");
}
//抛异常
result = annotationAction;
}
}
//result为null,说明没有解析到
if (result == null) {
if (allowContinuation) {
try {
if (Utils.getRawType(parameterType) == Continuation.class) {
isKotlinSuspendFunction = true;
return null;
}
} catch (NoClassDefFoundError ignored) {
}
}
throw parameterError(method, p, "No Retrofit annotation found.");
}
//返回
return result;
}
就是一个方法parseParameterAnnotation(),这个方法就是获取参数注解中的key ,并封装返回,方法太长了,自行查看。