1、Retrofit与其他网络请求框架的区别?
功能、性能、使用场景
优点:Retrofit基于OkHttp、通过注解来配置请求方法的类型、请求头、请求参数,支持同步、异步请求,可以使用多种Converter对数据进行解析,例如gson、xml,并且支持RxJava。因为OkHttp是基于NIO和Okio的,所以性能更好,请求处理速度都很快。
使用场景:任何场景下优先选择,尤其是项目中运用了RxJava、后台的api遵循了restful风格。
运用到的设计模式:外观模式、构建者模式、动态代理、策略模式
外观模式:将一些复杂的功能进行统一封装,使外部用户更简单的使用,比如Retrofit这个类
构建者模式:比如说Retrofit这个类的实例化
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://gank.io/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
动态代理:
Api api = retrofit.create(Api.class);
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, 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 serviceMethod = loadServiceMethod(method);
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
策略模式:
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
这两个操作其实是分别加入到了两个集合中
private final List<Converter.Factory> converterFactories;
private final List<CallAdapter.Factory> adapterFactories;
后面对返回的数据进行解析是遍历的converterFactories这个集合,对网络请求进行适配则是遍历adapterFactories这个集合(支持4个),默认这个集合会添加一个,不过在集合末尾
在调用build()方法构建Retrofit实例时
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);
}
几个重要的变量:
- callFactory 这儿直接new了OKHttpClient 所以Retrofit是使用了OkHttp
- callbackExecutor = platform.defaultCallbackExecutor()
我们这里假设没有配置.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
这个callbackExecutor是在网络请求返回数据时进行线程切换的,切换到主线程
static class Android extends Platform {
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
@Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
return new ExecutorCallAdapterFactory(callbackExecutor);
}
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
可以看到这儿的Handler中的looper是从主线程中拿的。
return serviceMethod.callAdapter.adapt(okHttpCall);
这个callAdapter是从adapterFactories这个集合中遍历获取的
for (int i = start, count = adapterFactories.size(); i < count; i++) {
CallAdapter<?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
这个集合的初始化
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));
return serviceMethod.callAdapter.adapt(okHttpCall);
这儿调用adapt()方法
@Override public <R> Call<R> adapt(Call<R> call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
static final class ExecutorCallbackCall<T> implements Call<T>
这个跟OkHttpCall一样都实现了Call接口,标准的静态代理的写法
ServiceMethod serviceMethod = loadServiceMethod(method);
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
final class OkHttpCall<T> implements Call<T>
所以在请求的时候调用
@Override public void enqueue(final Callback<T> callback) {
if (callback == null) throw new NullPointerException("callback == null");
delegate.enqueue(new Callback<T>() {
@Override public void onResponse(final Call<T> call, final Response<T> response) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
if (delegate.isCanceled()) {
// Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation.
callback.onFailure(call, new IOException("Canceled"));
} else {
callback.onResponse(call, response);
}
}
});
}
@Override public void onFailure(final Call<T> call, final Throwable t) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
callback.onFailure(call, t);
}
});
}
});
}
call.enqueue()发起异步请求时,其实是直接调到这儿来了,在onResponse中直接通过callbackExecutor来切换到主线程
网友评论