就会触发InvocationHandler的invoke方法的调用来完成listRepos接口的实现:返回一个Call< T>对象。
在invoke方法中,调用loadServiceMethod加载一个ServiceMethod对象,如果已经加载过了,则会从缓存中获取,如果没有缓存,则会创建一个新的ServiceMethod对象,在创建过程中完成了对网络接口方法的解析,进而封装成一个ServiceMethod对象。ServiceMethod对象中的成员变量如下:
final class ServiceMethod<R,T>{
final okhttp3.Call.Factory callFactory;
final CallAdapter<R,T> callAdapter;
private final HttpUrl baseUrl;
private final Converter<RespinseBody,R> respinserConverter;
private final String httpMethod; //请求方法:POST GET等
private final String relativeUrl;
private final Headers headers; //请求头
private final MediaType contentType;
…
}
这些成员变量大部分都是通过解析网络接口方法的注解完成初始化的。在获取到ServiceMethod对象后,使用它完成OkHttpCall< Object>对象的创建。最后通过代码:
return serviceMethod.callAdapter.adapt(okHttpCall);
返回一个对象。这个对象在当前示例下返回的是一个 ExecutorCallbackCall对象,它的创建过程还是比较复杂的,首先serviceMethod中的callAdapter对象是由createCallAdapter创建,而 createCallAdater内部是使用Retrofit对象来获取一个CallAdapter对象,createCallAdapter的调用和实现如下:
public ServiceMethod build() {
callAdapter = createCallAdapter();
}
private CallAdapter<?> createCallAdapter() {
…
try {
return 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);
}
}
…
callAdapter方法会遍历CallAdapter.Factory集合adapterFactories,根据网络接口方法的返回值来匹配CallAdapter对象,进而返回对应的CallAdapter。Retrofit的callAdapter方法的实现如下:
//Retrofit.java
public CallAdapter<?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
public CallAdapter<?> nextCallAdapter(CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
checkNotNull(returnType, “returnType == null”);
checkNotNull(annotations, “annotations == null”);
int start = adapterFactories.indexOf(skipPast) + 1;
//遍历CallAdapter.Factory集合
for (int i = start, count = adapterFactories.size(); i < count; i++) {
//根据网络接口的返回类型匹配相对应的CallAdapter.Factroy,进而获取CallAdapter对象
CallAdapter<?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
…
throw new IllegalArgumentException(builder.toString());
}
之前在创建Retrofit对象的时候,会默认添加一个ExecutorCallAdapterFactroy对象到CallAdapter.Factory的集合中。
所以在遍历CallAdapter.Factroy集合遍历到ExecutorCallAdapterFactory对象时,就会调用该对象的get方法获取一个CallAdapter对象:
//ExecutorCallAdapterFactory.java
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
Class<?> rawType = getRawType(returnType);
// 如果匹配的类型不为Call则返回null
if (rawType != Call.class) {
return null
}
final Type responseType = Utils.getCallResponseType(returnType);
//返回一个CallAdapter对象
return new CallAdapter<Object,Call<?>>{
@Override
public Type responseType(){
return responseType
}
@Override
public Call adapter(Call call){
return new ExecutorCallback<>(callbackExecutor,call);
}
}
}
在get方法中会根据网络接口的返回类型进行匹配,如果返回类型不为Call,则返回null,如果为Call类型,比如网络接口方法listRepos的返回类型为Call,那么就会通过判断来返回一个CallAdapter对象。再回到之前的代码:
serviceMethod.callAdapter.adapter(okHttpCall);
所以serviceMethod.callAdapter实际上是获取的是CallAdapter对象,CallAdapter对象的adapter方法会返回一个ExecutorCallbackCall对象。
所以,如果网络接口的返回类型为Call类型,那么在InvocationHandler的invoke方法中返回对象的类型为ExecutorCallbackCall。
通过网络接口的的实现可知,调用接口方法如下:
Call<List> octocat = getHubService.listRepos(“octocat”);
返回的Call对象实际上是ExecutorCallbackCall对象,所以接下来我们使用Call对象发送网络请求,如异步网络请求:
octocat.enqueue(mCallback);
实际上执行的是ExecutorCallbackCall中的enqueue方法,enqueue方法的实现如下:
@Override
public void enqueue(final Callback callback) {
…
call.enqueue(new okhttp3.Callback() {
//内部使用okhttp完成异步请求
@Override
//网络成功的回调
public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse)
throws IOException {
Response response;
try {
response = parseResponse(rawResponse);
} catch (Throwable e) {
callFailure(e);
return;
}
callSuccess(response);
}
…
});
在enqueue方法内部,最终使用OkHttp执行网络请求,网络响应或失败都会通过MainThreadExecutor分发到主线程。
- 从Retrofit的
build
方法 建造出一个 Retrofit对象,过程中有两个重要的工厂集合:
(1)adapterFactories
集合,是CallAdapter的工厂实现类,里面装着网络回调执行器callbackExecutor(就是绑定主线程的Handler)
(2)converterFactories
集合,Converter的工厂实现类,里面装着网络响应转化器,比如说Gson
- 网络接口的实现为Retrofit的最终要的逻辑,也就是其
create
方法
通过动态代理将网络接口转化成一个ServiceMethod
对象,这个ServiceMethod中封装了网络请求的所有信息,然后通过 OkHttpCall<>(ServiceMehtod,args)
来封装成一个OkhttpCall对象,最后用这个OkHttpCall通过callAdapter
方法 遍历一开始的adapterFactories集合,通过get
方法最终来返回与网络接口匹配的CallAdapter对象。
- 通过create最终创造的CallAdapter对象可以通过调用其接口方法其实现一个同步/异步请求。
在异步请求中,enqueue
实际上就是调用CallAdapter的enqueue方法 通过OkHttp
实现网络请求,执行的结果通过MainThreadExecutor对象回调到主线程中。
有人就会问了,为什么Retrofit的网络请求是基于Okhttp,我们要去用Retrofit,而不是直接去用OkHttp呢?
我们先来看看OkHttp的特点:
- 支持SPDY,因此可以同一IP多个连接共享同一个socket(SPDY并不是一种用于替代HTTP的协议,而是对HTTP协议的增强)
最后
下面是辛苦给大家整理的学习路线,有需要的可以点击这里免费获取
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
ndroid移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**
[外链图片转存中…(img-QsVXDDoN-1710984052228)]
[外链图片转存中…(img-eQkJVe6d-1710984052229)]
[外链图片转存中…(img-sjESChOH-1710984052229)]
[外链图片转存中…(img-GIHQARkD-1710984052230)]
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
[外链图片转存中…(img-iGRn3Ens-1710984052230)]