此篇文章根据stay课程做的笔记,只是大概讲解了一下retrofit的整的流程,细节处尚未做分析。视频地址http://www.stay4it.com/my/course/22
基本网络请求workflow
所有的网络框架请求基本都会遵循下图的workflow,retrofit也不例外,retrofit是一个类型安全的http请求框架,因为它声明了泛型,因此在使用过程中,外层不需要考虑数据的反序列化,框架会通过converter实现。
image.png
1.request:封装request,加入请求队列。由注解实现,通过配置请求参数实现request的封装,好处是以后在改动过程中,只需要改动底层,上层不用改。
2.executor:进入looper循环,如果有空闲线程,就执行http请求。这里是retrofit的关键封装,由calladapter将call转化成相应的泛型T
3.HTTP Call:拿到服务器,bytes流,进行反序列化,未做封装主要有OKhttp实现
4.数据返回:回到上层,进行UI刷新,将二进制流做序列化处理,converter转换成想要的对象
sample
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(INewsApi.HOST)
.client(builder.build())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
build方法
retrofit是通过build模式获取了实例,下面是retrofit的build方法的思维导图,讲解了大致的retrofit创建实例的过程
image.png
public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
// Make a defensive copy of the adapters and add the default Call adapter.
List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
// Make a defensive copy of the converters.
List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);
return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
callbackExecutor, validateEagerly);
}
可以从代码中看到retrofit对象的建立大概分为六个参数,这里着重讲四个
callFactory :说明现如今retrofit只支持OKhttpclient
converterFactories :扩展功能,gsonfactory等等
callbackExecutor :这个参数主要是将提供一个主线程
adapterFactories:传入了callbackExecutor 参数,里面还会有一个方法是将传入的call类型(其实实际上是OKhttpcall)转化为call,里面最重要的是将利用callbackExecutor 将子线程里的东西转化为主线程。当执行onresponse()方法时,就会回到上层的call.enqueue()方法,从而拿到数据。
create方法
这个方法主要是创造相应的API实例对象,这里也是从主线讲大概。下图为create方法的流程图
image.png
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();
@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.
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
这里主要采用了动态代理模式,当api调用相应的方法后,动态代理会进行拦截操作,将接口中的方法注解取出来,适配成OKhttpcall,这个过程主要由servicemethod方法来完成,后来将servicemethod方法作为参数传入OKhttp中,构成实例,最后将OKhttpcall转化为call,进而和上面ExecutorCallAdapterFactory类相连接,完成数据的接收工作。
2018/03/28更新补充笔记-------------从细节处看retrofit
create():
ServiceMethod<Object, Object> serviceMethod =(ServiceMethod<Object,Object>)loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
①servicemethod:带缓存的注解解析类,里面的loadServiceMethod()方法中含有serviceMethodCache。作为缓存,因此不会重复解析api中的方法。
Servicemethod.java
这个类比较关键,是通过builder模式创建的实例,看一下build方法
callAdapter = createCallAdapter():calladapter是调用了retrofit.callAdapter()方法获得的
接下来回到retrofit类中的callAdapter方法
nextCallAdapter()——>通过遍历adapterFactories确定项目所需要的calladapter
adapterFactories又是从何而来的呢,还记得在retrofit的build方法中传入的那几个参数吗,其中有一个就是adapterFactories,这个类包含三种(java,rxjava,android)通过每个factory的get方法来确定,API到底是最后要的是那个类型,observerble还是call。这里以call类型作为参考。
因此带有calladapter的servicemethod就生成了
② 然后来看第三行代码就是adapter中的adapt方法
我们刚刚说了,这个servicemethod中的adapter是默认的ExecutorCallAdapterFactory,然后来看adapt方法。
它将callbackExecutor和传进来的OKhttpcall一同传入到ExecutorCallbackCall中,这个OKhttpcall参数后来变成了delegate,然后执行了enqueue方法。然后又将重点引入到了OKhttpcall中的enqueue方法中,走到这一步已经脱离了retrofit,进入到了OKhttp中
在okhttpcall中还有一个enqueue方法,这个实现类属于OKhttp的realcall方法
@Override public void enqueue(Callback responseCallback) {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
eventListener.callStart(this);
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
这里的realcall的enqueue方法引入了AsyncCall这个异步的call类,当然还有execute同步方法是直接执行的请求操作。
然后回到刚刚ExecutorCallAdapterFactory类中,里面delegate的enqueue方法传入了一个callback,里面使用到了主线程callbackExecutor,将OKhttpcall中的子线程操作转移到了主线程中
// 创建 网络请求接口 的实例
GetRequest_Interface request = retrofit.create(GetRequest_Interface.class);
//对 发送请求 进行封装
Call<Reception> call = request.getCall();
call.enqueue(new Callback<Translation>() {
//请求成功时回调
@Override
public void onResponse(Call<Translation> call, Response<Translation> response) {
//请求处理,输出结果
response.body().show();
}
//请求失败时候的回调
@Override
public void onFailure(Call<Translation> call, Throwable throwable) {
System.out.println("连接失败");
}
});
以上为一个小的例子,这里的call就是通过create创造出来的包含泛型的ExecutorCallbackCall,继而调用它内部的enqueue方法,将数据拿到主线程中
网友评论