Retrofit
作为
Square
公司出品非常受欢迎的的http网络请求框架,使用了非常多的设计模式,非常值得我们学习。今天我就给大家分析一下其中
CallAdapter
中使用到的设计模式。
CallAdapter
在Retrofit
中的是通过Retrofit.Builder
中的addCallAdapterFactory(CallAdapter.Factory factory)
方法添加的CallAdapter.Factoy
,直接看使用代码:
public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
callAdapterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
然后在需要CallAdapter
的时候,通过CallAdapter.Factoy
的get()
方法来获取对象CallAdapter
public interface CallAdapter<R, T> {
......
/**
* Returns an instance of {@code T} which delegates to {@code call}.
*
*/
T adapt(Call<R> call);
/**
* Creates {@link CallAdapter} instances based on the return type of {@linkplain
* Retrofit#create(Class) the service interface} methods.
*/
abstract class Factory {
/**
* Returns a call adapter for interface methods that return {@code returnType}, or null if it
* cannot be handled by this factory.
*/
public abstract @Nullable CallAdapter<?, ?> get(Type returnType, Annotation[] annotations,
Retrofit retrofit);
.......
}
}
适配器模式(Adapter Pattern):将一个接口转换成客户希望的另一个接口,使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。
CallAdapter
名字就包含适配器Adapter
,也算“人如其名”,使用到了适配器模式。我们来看下CallAdapter
接口中的adapt()
方法:
public interface CallAdapter<R, T> {
......
/**
* Returns an instance of {@code T} which delegates to {@code call}.
*
*/
T adapt(Call<R> call);
}
就是将一个Call
对象转换成一个泛型T
所代表的对象,简单清晰明了。
适配器模式(Adapter Pattern):工厂方法模式将生成具体产品的任务分发给具体的产品工厂。
CallAdapter
的生成都交给其工厂实现类,比如RxJava2CallAdapter
的工厂类RxJava2CallAdapterFactory
:
public final class RxJava2CallAdapterFactory extends CallAdapter.Factory {
.......
@Override public @Nullable CallAdapter<?, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit) {
Class<?> rawType = getRawType(returnType);
if (rawType == Completable.class) {
// Completable is not parameterized (which is what the rest of this method deals with) so it
// can only be created with a single configuration.
return new RxJava2CallAdapter(Void.class, scheduler, isAsync, false, true, false, false,
false, true);
}
.......
if (rawType != Observable.class && !isFlowable && !isSingle && !isMaybe) {
return null;
}
.......
return new RxJava2CallAdapter(responseType, scheduler, isAsync, isResult, isBody, isFlowable,
isSingle, isMaybe, false);
}
}
使用配置的时候也都是配置的CallAdapter
的工厂类。
**策略模式(Strategy):**定义了一组算法,将每个算法都封装起来,并且使它们之间可以互换。
前面在CallAdapter
的使用中我们看到可以添加多个CallAdapter.Factory
对象,相当于我们封装了多个不同的适配算法CallAdapter.adapt()
。那么接下来我们来看看源码中是不是真的在其中匹配了某个CallAdapter
。CallAdapter
对象的生成和调用其实实在HttpServerMethod
对象的parseAnnotations()
方法里触发的,parseAnnotations()->createCallAdapter()
:
abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
/**
* Inspects the annotations on an interface method to construct a reusable service method that
* speaks HTTP. This requires potentially-expensive reflection so it is best to build each service
* method only once and reuse it.
*/
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
.......
if (isKotlinSuspendFunction) {
......
CallAdapter<ResponseT, ReturnT> callAdapter =
createCallAdapter(retrofit, method, adapterType, annotations);
Type responseType = callAdapter.responseType();
......
}
......
}
private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
Retrofit retrofit, Method method, Type returnType, Annotation[] annotations) {
try {
//noinspection unchecked
return (CallAdapter<ResponseT, ReturnT>) retrofit.callAdapter(returnType, annotations);
} catch (RuntimeException e) {
.......
}
}
}
然后回到Retrofit
对象的callAdapter() -> nextCallAdapter()
public final class Retrofit {
......
public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
checkNotNull(returnType, "returnType == null");
checkNotNull(annotations, "annotations == null");
int start = callAdapterFactories.indexOf(skipPast) + 1;
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
......
}
......
}
在的nextCallAdapter()
方法中,根据返回值retrunType
类型遍历调用CallAdapter.Factory
的get()
方法,如果返回的CallAdapter对象部位null
则直接返回改对象,说明CallAdapter.Factory
的get()
应该是根据retrunType
确定是否返回CallAdapter
对象(是否选择该种策略)。下面看两种默认实现的CallAdapter.Factory
:
public final class RxJava2CallAdapterFactory extends CallAdapter.Factory {
......
@Override public @Nullable CallAdapter<?, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit) {
Class<?> rawType = getRawType(returnType);
......
if (rawType != Observable.class && !isFlowable && !isSingle && !isMaybe) {
return null;
}
.......
}
}
public final class DefaultCallAdapterFactoryextends CallAdapter.Factory {
......
@Override public @Nullable CallAdapter<?, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
.......
}
}
由于本篇主要分析设计模式的使用流程,所以去掉了大部分的代码,只保留了最核心的,与设计模式有关的代码,力求最简单的方式呈现设计模式的使用流程。文中提到了两种设计模式的使用:
Call
对象转换成我们想要的目标对象,比如RxJava
的Observable
由于个人水平可能有限,如果上述博文有不正确的地方,欢迎大家指正