我们来看bindToLifecycle()方法:
public abstract class RxAppCompatActivity extends AppCompatActivity implements LifecycleProvider {
private final BehaviorSubject lifecycleSubject = BehaviorSubject.create();
public final LifecycleTransformer bindToLifecycle() {
//执行了这行代码,返回了LifecycleTransformer
return RxLifecycleAndroid.bindActivity(lifecycleSubject);
}
}
不难猜测,实际上,那个神秘人,就是我们RxAppCompatActivity 中的BehaviorSubject成员变量(它本身就是一个Observable)!
我们点进去看看:
//1.执行了 bind(lifecycle, ACTIVITY_LIFECYCLE);
public static LifecycleTransformer bindActivity(@NonNull final Observable lifecycle) {
return bind(lifecycle, ACTIVITY_LIFECYCLE);
}
//2.执行了bind(takeUntilCorrespondingEvent(lifecycle.share(), correspondingEvents))
public static LifecycleTransformer bind(@Nonnull Observable lifecycle,
@Nonnull final Function correspondingEvents) {
return bind(takeUntilCorrespondingEvent(lifecycle.share(), correspondingEvents));
}
//3.最终抵达这里,这个方法执行了什么呢?
private static Observable takeUntilCorrespondingEvent(final Observable lifecycle,
final Function correspondingEvents) {
return Observable.combineLatest(
lifecycle.take(1).map(correspondingEvents),
lifecycle.skip(1),
new BiFunction() {
@Override
public Boolean apply(R bindUntilEvent, R lifecycleEvent) throws Exception {
return lifecycleEvent.equals(bindUntilEvent);
}
})
.onErrorReturn(Functions.RESUME_FUNCTION)
.filter(Functions.SHOULD_COMPLETE);
}
最后我们走到了3,我们一行一行分析:
Observable.combineLatest
这行代码实际上是将lifecycle(就是我们传进来的BehaviorSubject)的事件进行了一次分割:
lifecycle.take(1)指的是最近发射的事件,比如说我们在onCreate()中执行了bindToLifecycle,那么lifecycle.take(1)指的就是ActivityEvent.CREATE,经过map(correspondingEvents),这个map中传的函数就是 1中的ACTIVITY_LIFECYCLE:
private static final Function ACTIVITY_LIFECYCLE =
new Function() {
@Override
public ActivityEvent apply(ActivityEvent lastEvent) throws Exception {
switch (lastEvent) {
case CREATE:
return ActivityEvent.DESTROY;
case START:
return ActivityEvent.STOP;
case RESUME:
return ActivityEvent.PAUSE;
case PAUSE:
return ActivityEvent.STOP;
case STOP:
return ActivityEvent.DESTROY;
case DESTROY:
throw new OutsideLifecycleException("Cannot bind to Activity lifecycle when outside of it.");
default:
throw new UnsupportedOperationException("Binding to " + lastEvent + " not yet implemented");
}
}
};
也就是说,lifecycle.take(1).map(correspondingEvents)实际上是返回了 CREATE 对应的事件 DESTROY ,它意味着本次订阅将在Activity的onDestory进行取消。
lifecycle.skip(1)就简单了,除去第一个保留剩下的,以ActivityEvent.Create为例,这里就剩下:
ActivityEvent.START
ActivityEvent.RESUME
ActivityEvent.PAUSE
ActivityEvent.STOP
ActivityEvent.DESTROY
第三个参数 意味着,lifecycle.take(1).map(correspondingEvents)的序列和 lifecycle.skip(1)进行combine,形成一个新的序列:
false,false,fasle,false,true
这意味着,当Activity走到onStart生命周期时,为false,这次订阅不会取消,直到onDestroy,为true,订阅取消。
而后的onErrorReturn和filter是对异常的处理和判断是否应该结束订阅:
//异常处理
static final Function RESUME_FUNCTION = new Function() {
@Override
public Boolean apply(Throwable throwable) throws Exception {
if (throwable instanceof OutsideLifecycleException) {
return true;
}
Exceptions.propagate(throwable);
return false;
}
};
//是否应该取消订阅,可以看到,这依赖于上游的boolean
static final Predicate SHOULD_COMPLETE = new Predicate() {
@Override
public boolean test(Boolean shouldComplete) throws Exception {
return shouldComplete;
}
};
bind生成LifecycleTransformer
看懂了3,我们回到2,我们生成了一个Observable,然后通过bind(Observable)方法,生成LifecycleTransformer并返回:
public static LifecycleTransformer bind(@Nonnull final Observable lifecycle) {
return new LifecycleTransformer<>(lifecycle);
}
神秘人的神秘面纱就此揭开。
总结
RxLifecycle并不难以理解,相反,它的设计思路很简单:
1.在Activity中,定义一个Observable(Subject),在不同的生命周期发射不同的事件;
2.通过compose操作符(内部实际上还是依赖takeUntil操作符),定义了上游数据,当其接收到Subject的特定事件时,取消订阅;
3.Subject的特定事件并非是ActivityEvent,而是简单的boolean,它已经内部通过combineLast操作符进行了对应的转化。
实际上,Subject和ActivityEvent对RxLifecycle的使用者来讲,是对应隐藏的。我们只需要调用它提供给我们的API,而内部的实现者我们无需考虑,但是也只有去阅读和理解了它的思想,我们才能更好的选择使用这个库。
转折:AutoDispose
在我沉迷于RxLifecycle对项目的便利时,一个机会,我有幸阅读到了 Daniel Lew 的文章《Why Not RxLifecycle?》(为什么放弃使用RxLifecycle)。
作为RxLifecycle的作者,Daniel Lew客观陈述了使用RxLifecycle在开发时所遇到的窘境。并且为我们提供了一个他认为更优秀的设计:
AutoDispose: Automatic binding+disposal of RxJava 2 streams.
我花了一些时间研究了一下AutoDispose,不得不承认,AutoDispose相比较RxLifecycle,前者更加健壮,并且拥有更优秀的拓展性,如果我的项目需要一个处理RxJava自动取消订阅的库,也许AutoDispose更为适合。
更让我感到惊喜的是,AutoDispose的设计思想,有很大一部分和RxLifecycle相似,而且我在其文档上,看到了Uber的工程师对于Daniel Lew 所维护的 RxLifecycle 感谢,也感谢Daniel Lew 对于 AutoDispose的很大贡献:
以下摘录于AutoDispose的官方文档:
Special thanks go to Dan Lew (creator of RxLifecycle), who helped pioneer this area for RxJava in android and humored many of the discussions around lifecycle handling over the past couple years that we've learned from. Much of the internal scope resolution mechanics of
AutoDispose are inspired by RxLifecycle.
在我尝试将AutoDispose应用在项目中时,我发现国内对于这个库所应用的不多,我更希望有更多朋友能够和我一起使用这个库,于是我准备写一篇关于AutoDispose使用方式的文章。
但在这之前,我还是希望能够先将RxLifecycle的个人心得分享给大家,原因有二:
一是RxLifecycle更简单,原理也更好理解,学习一个库不仅仅是为了会使用它,我们更希望能够从源码中学习到作者优秀的设计和思想。因此,如果是从未接触过这两个库的开发者,直接入手AutoDispose,在我看来不如先入手RxLifecycle。
二是AutoDispose的很大一部分设计核心源于RxLifecycle,理解了RxLifecycle,更有利于AutoDispose的学习。
作者:却把清梅嗅
链接:https://www.jianshu.com/p/8311410de676
来源:
著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。