Call listRepos(@Path(“user”) String user);
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(“https://api.github.com/”)
.build();
GitHubService service = retrofit.create(GitHubService.class);
Call repos = service.listRepos(“octocat”);
retrofit实例的创建,使用了builder模式,从下面的源码中可以看出
public static final class Builder {
Builder(Platform platform) {
this.platform = platform;
converterFactories.add(new BuiltInConverters());
}
public Builder() {
// Platform.get()方法可以用于判断当前的环境
this(Platform.get());
}
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 Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException(“Base URL required.”);
}
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();// 新建Client,留到之后newCall什么的
}
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
// Make a defensive copy of the adapters and add the default Call adapter.
List
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
// Make a defensive copy of the converters.
List
return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
callbackExecutor, validateEagerly);
}
}
好玩的地方开始了,我们先来看看这个方法
public T create(final Class service) {
Utils.validateServiceInterface(service);
if (validateEagerly) {
eagerlyValidateMethods(service);
}
// 动态代理,啦啦啦
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class>[] { service },
new InvocationHandler() {
// platform 可以分辨出你是在android,还是java8,又或者别的
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.
// 这里的invoke,Object方法都走这里,比如equals、toString、hashCode什么的
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
// java8默认方法,1.8的新特性
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
// 这里是核心代码了
ServiceMethod serviceMethod =
(ServiceMethod) loadServiceMethod(method);
OkHttpCall okHttpCall &#61; new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
可以看出创建API使用了动态代理&#xff0c;根据接口动态生成的代理类&#xff0c;将接口的都转发给了负责连接代理类和委托类的InvocationHandler实例&#xff0c;接口方法也都通过其invoke方法来处理。
在invoke方法中&#xff0c;首先会通过Platform.get()方法判断出当前代码的执行环境&#xff0c;之后会先把Object和Java8的默认方法进行一个处理&#xff0c;也是在进行后续处理之前进行去噪。其中的关键代码其实就是最后三句&#xff0c;这也是这篇文章将要分析的
erviceMethod, ?> loadServiceMethod(Method method) {
// 从缓存里面取出&#xff0c;如果有的话&#xff0c;直接返回好了
ServiceMethod, ?> result &#61; serviceMethodCache.get(method);
if (result !&#61; null) return result;
synchronized (serviceMethodCache) {
result &#61; serviceMethodCache.get(method);
if (result &#61;&#61; null) {
// 为null的话&#xff0c;解析方法的注解和返回类型、参数的注解he参数类型&#xff0c;新建一个ServiceMethod
result &#61; new ServiceMethod.Builder<>(this, method).build();// ->
// 新建的ServiceMethod加到缓存列表里面
serviceMethodCache.put(method, result);
}
}
return result;
}
CallAdapter和Converter等到后面再分析&#xff0c;这里先看看parseMethodAnnotation(annotation)&#xff0c;功能和其名字一样&#xff0c;其对方法注解进行了解析
/**
在解析注解时&#xff0c;先通过instanceof判断出注解的类型&#xff0c;之后调用parseHttpMethodAndPath方法解析注解参数值&#xff0c;并设置httpMethod、relativeUrl、relativeUrlParamNames等属性。
上面说了API中方法注解的解析&#xff0c;现在来看看方法参数注解的解析&#xff0c;这是通过调用parseParameterAnnotation方法生成ParameterHandler实例来实现的&#xff0c;代码比较多&#xff0c;这里挑选&#64;Query来看看。
else if (annotation instanceof Query) {
Query query &#61; (Query) annotation;
String name &#61; query.value();
boolean encoded &#61; query.encoded();
Class> rawParameterType &#61; Utils.getRawType(type);// 返回基础的类
gotQuery &#61; true;
// 可以迭代&#xff0c;Collection
if (Iterable.class.isAssignableFrom(rawParameterType)) {
if (!(type instanceof ParameterizedType)) {
throw parameterError(p, rawParameterType.getSimpleName()
在&#64;Query中&#xff0c;将分成Collection、array、other三种情况处理参数&#xff0c;之后根据这些参数&#xff0c;调用ParameterHandler中的Query静态类&#xff0c;创建出一个ParameterHandler实例。这样循环直到解析了所有的参数注解&#xff0c;组合成为全局变量parameterHandlers&#xff0c;之后构建请求时会用到
ServiceMethod创建完成之后&#xff0c;我们来看看下一行代码中的OkHttpCall类&#xff0c;里面的包含了请求的执行和响应处理&#xff0c;我们来看看异步请求的做法
OkHttpCall(ServiceMethod
this.serviceMethod &#61; serviceMethod;
this.args &#61; args;
}
&#64;Override public void enqueue(final Callback callback) {
checkNotNull(callback, “callback &#61;&#61; null”);
okhttp3.Call call;
Throwable failure;
synchronized (this) {
if (executed) throw new IllegalStateException(“Already executed.”);
executed &#61; true;
call &#61; rawCall;
failure &#61; creationFailure;
if (call &#61;&#61; null && failure &#61;&#61; null) {
try {
call &#61; rawCall &#61; createRawCall();// 创建OkHttp3.Call
} catch (Throwable t) {
failure &#61; creationFailure &#61; t;
}
}
}
if (failure !&#61; null) {
callback.onFailure(this, failure);
return;
}
if (canceled) {
call.cancel();
}
call.enqueue(new okhttp3.Callback() {
这个题库内容是比较多的&#xff0c;除了一些流行的热门技术面试题&#xff0c;如Kotlin&#xff0c;数据库&#xff0c;Java虚拟机面试题&#xff0c;数组&#xff0c;Framework &#xff0c;混合跨平台开发&#xff0c;等
些流行的热门技术面试题&#xff0c;如Kotlin&#xff0c;数据库&#xff0c;Java虚拟机面试题&#xff0c;数组&#xff0c;Framework &#xff0c;混合跨平台开发&#xff0c;等
[外链图片转存中…(img-WajqqjLL-1644035867733)]
[外链图片转存中…(img-xYBDTmpP-1644035867734)]
下载方法&#xff1a;点赞&#43;关注后 点击【Android高级工程师进阶学习】即可领取&#xff01;