May you return with a young heart after years of fighting.
愿你出走半生,归来仍是少年。
Retrofit内部封装 OKHttp,采用注解的方式发起网络请求,同时融合 Rxjava,加入优雅的异步处理方式,使得其更加强大。
Retrofit的使用
定义接口
public interface BaiduService {
@GET(".")
Call<String> getBaidupage();
@GET(".")
Observable<String> getBaidu();
}
Retrofit请求
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://www.baidu.com")
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
//动态代理的方法生成接口实现类
BaiduService baiduService = retrofit.create(BaiduService.class);
//结合RxJava
Observable<String> baidu = baiduService.getBaidu();//创建Observable
baidu.subscribeOn(Schedulers.newThread())//子线程订阅访问网络
.observeOn(AndroidSchedulers.mainThread())//主线程观察
.subscribe(new BaseObserver<String>() {//产生订阅关系
@Override
public void onSuccess(String s) {
Log.e("Result", s);
}
@Override
public void onFail(Throwable e) {
Log.e("Fail", e.getMessage());
}
});
Retrofit使用的关键一步就是Retrofit.create函数创建接口动态代理,查看源码
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.adapt(okHttpCall);
}
});
}
关键的三步:
1 加载对应method的ServiceMethod实例
ServiceMethod<?, ?> loadServiceMethod(Method method) {
ServiceMethod<?, ?> result = serviceMethodCache.get(method);//是否有缓存
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);//同步代码块里是否有缓存
if (result == null) {
//创建
result = new ServiceMethod.Builder<>(this, method).build();
serviceMethodCache.put(method, result);//缓存起来
}
}
return result;
}
先去查看ServiceMethod是否有缓存,有的话直接取出,没有就创建,采用Builder模式,并用map缓存起来。
2 使用ServiceMethod实例和方法调用参数创建OkHttpCall
OkHttpCall是okhttp3.Call的一个包装类,实际调用OkHttpCall的相关执行方法时最终是调用OkHttpCall内部用ServiceMethod.callFactory创建的okhttp3.Call来执行网络请求。
3 调用serviceMethod.callAdapter.adapt(okHttpCall)来产生method所定义的返回(Call或者Observable或其他自定义CallAdapter支持的返回)。
这里以Rxjava的Observable为例,源码:
@Override public Object adapt(Call<R> call) {
Observable<Response<R>> responseObservable = isAsync
? new CallEnqueueObservable<>(call)
: new CallExecuteObservable<>(call);
Observable<?> observable;
if (isResult) {
observable = new ResultObservable<>(responseObservable);
} else if (isBody) {
observable = new BodyObservable<>(responseObservable);
} else {
observable = responseObservable;
}
if (scheduler != null) {
observable = observable.subscribeOn(scheduler);
}
if (isFlowable) {
return observable.toFlowable(BackpressureStrategy.LATEST);
}
if (isSingle) {
return observable.singleOrError();
}
if (isMaybe) {
return observable.singleElement();
}
if (isCompletable) {
return observable.ignoreElements();
}
return observable;
}
RxJavaCallAdapterFactory创建的callAdapter在执行adapt时将OkHttpCall包装一个Rx的Observable,在Observable被subscribe时才会真正的执行http请求。
框架所用到的设计模式
A.建造者模式:Retrofit创建
B.工厂模式:addCallAdapterFactory
C.外观模式:内部封装OkHttp等
D.策略模式:adapt()不同对象不同策略方法实现
E.适配器模式:RxJavaCallAdapterFactory,Java8CallAdapterFactory,GuavaCallAdapterFactory
F.动态代理模式:create方法
G.观察者模式:RxJava