RxJava 的 Observable subscribe() 后會返回 Subscription(RxJava2 是在 onSubscribe(Disposable d)),我們都知道在 Activity 退出的時候要執行 subscription.unsubscribe()。每個 Observable 訂閱后,都要我們寫一些管理 Subscription 的代碼,于是懶惰的人們發現了 RxLifecycle,只要自己的 Activity extends RxActivity(還有其他的,不一一列舉),然后就只要一行代碼,就可以根據 Activity 生命周期自動取消訂閱
observable
...
.compose(this.<>bindUntilEvent(ActivityEvent.DESTROY))
.subscribe(...);
在 Activity 或 Fragment 里,這樣寫的確很方便,只是如果我們的架構是 MVP 或者 MVVM,那么在 P 層、VM 層,如何寫呢?
我的設計是這樣的,有一個數據提供者 DataProvider,當然是單例,比如
DataProvider.get().getNews() --> 返回 Observable<News>
DataProvider.get().getLoginUser() --> 返回 Observable<User>
如果需要綁定當前對象
DataProvider.get().tag(this).getNews()
DataProvider.get().tag(this).getLoginUser()
這個 tag 方法的參數是 Object(你應該能想象到,這個 Object 必然是某一個 Map 的 key)
然后在 Activity onDestroy() 中
DataProvider.get().cancel(this);
既然這個 tag 方法的參數是 Object,那么 P 層、VM 層中就方便了,綁定時就直接 tag(this),然后應該有一個 BasePresenter 或 BaseViewModel,里面寫個 destroy() 方法,在 Activity onDestroy() 中調用 viewModel.destroy() 就完事了。
public class BaseViewModel {
public void destroy() {
DataProvider.get().cancel(this);
}
}
所以關鍵是 DataProvider 到底是怎么實現的
public abstract class AbstractDataProvider implements WebService {
protected Map<Object, AbstractDataProvider> providerMap = new WeakHashMap<>();
private CompositeSubscription subscription = new CompositeSubscription();
public void cancel(Object target) {
AbstractDataProvider provider = providerMap.get(target);
if (provider == null) {
return;
}
provider.cancel();
}
public void cancel() {
subscription.unsubscribe();
for (AbstractDataProvider provider : providerMap.values()) {
provider.cancel();
}
}
private <T> Observable.Operator<T, T> bind() {
return new Observable.Operator<T, T>() {
@Override
public Subscriber<? super T> call(Subscriber<? super T> subscriber) {
subscription.add(subscriber);
return subscriber;
}
};
}
@Override
public Observable<News> getNewsList(String date) {
return WebServiceProvider.get().getNewsList(date).lift(this.<News>bind());
}
@Override
public Observable<TopNews> getTopNewsList() {
return WebServiceProvider.get().getTopNewsList().lift(this.<TopNews>bind());
}
}
DataProvider主要是比AbstractDataProvider多了tag()方法,tag()返回的是AbstractDataProvider,防止多次調用tag()
public class DataProvider extends AbstractDataProvider {
private static class DataProviderHolder {
private static final DataProvider INSTANCE = new DataProvider();
}
public static DataProvider get() {
return DataProviderHolder.INSTANCE;
}
private DataProvider() {
}
public AbstractDataProvider tag(Object target) {
AbstractDataProvider provider = providerMap.get(target);
if (provider == null) {
provider = new DataProvider();
providerMap.put(target, provider);
}
return provider;
}
}
源碼,主要包含
1、MVVM
2、RxJava 生命管理
3、Retrofit 二次動態代理
4、網絡請求本地緩存