这是一篇关于AutoDispose/RxLifecycle/Google Lifecycle的详细分析,以做记录。
Architecture Components Lifecycle
Google之前推出过一套Architecture Components,里面的Lifecycle组件是LiveData等的基础组件。

具体的生命周期过程不再介绍。我们来看google官网对整个生命周期流动的解释。
在该Lifecycle组件中,与传统的生命周期不同,只定义了五种状态,分别是:
- INITIALIZED 最初始的状态
- DESTROYED
- CREATED
- STARTED
- RESUMED
上图中向右的箭头很好理解,每过来一个events会发生生命周期状态的变更
向左的箭头可以看成状态的回滚, 如果在RESUMED状态发生了onPause()事件,则状态回滚到RESUMED之前的STARTED状态

这幅图是我看完源码后对整个架构的总结。整个组件由三大部分组成:LifecycleRegistry & LifecycleOwner & LifecycleObserver
LifecycleOwner
生命周期事件分发者。例如我们最熟悉的Activity/Fragment。它们在生命周期发生变化时发出相应的Event给LifecycleRegistry。
LifecycleObserver
生命周期监听者。通过注解将处理函数与希望监听的Event绑定,当相应的Event发生时,LifecycleRegistry会通知相应的函数进行处理。
LifecycleRegistry
控制中心。它负责控制state的转换、接受分发event事件。其实个人觉得Lifecycle组件与EventBus很类似? 但以下代码表现了他们的不同:
while (mObserverCurrentState != mState) {
Event event = mObserverCurrentState.isAtLeast(mState)
? downEvent(mObserverCurrentState) : upEvent(mObserverCurrentState);
mObserverCurrentState = getStateAfter(event);
mCallback.onStateChanged(mLifecycleOwner, event);
}
假设现在的状态为RESUMED,但是observer的状态还在CREATED,那么就会走upEvent(mObserverCurrentState)依次向observer发送start&resume事件。
假设现在的状态为CREATED,但是observer的状态还在RESUMED,说明observer状态超前了,那么就会走downEvent(mObserverCurrentState)依次向observer发送pause&stop事件。
侵入性问题
Lifecycle组件为了降低侵入性,首先通过registerActivityLifecycleCallbacks给每个启动的Activity创建了一个ReportFragment
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
if (activity instanceof FragmentActivity) {
((FragmentActivity) activity).getSupportFragmentManager()
.registerFragmentLifecycleCallbacks(mFragmentCallback, true);
}
// ProcessLifecycleOwner should always correctly work and some activities may not extend
// FragmentActivity from support lib, so we use framework fragments for activities
android.app.FragmentManager manager = activity.getFragmentManager();
if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
// Hopefully, we are the first to make a transaction.
manager.executePendingTransactions();
}
}
然后在ReportFragment中真正根据生命周期去触发Activity的Lifeycle事件。当然我并不明白它为什么不直接用ActivityLifecycleCallback非要通过Fragment中转。有知道的朋友解释一下~
RxLifecycle
因为Rxjava2的流行,顺其自然的出现了RxLifecycle组件,主要防止Rxjava的泄漏,在生命周期结束时取消Subscription

为了依旧实现Rxjava的链式调用,RxLifecycle很巧妙的使用了TakeUtil运算符
TakeUtil

看图非常容易理解,不再解释。
LifecycleProvider
与前面类似,Activity等作为生命周期的提供者LifecycleProvider,该Provider会提供一个转换器LifecycleTransformer

@Override
public ObservableSource<T> apply(Observable<T> upstream) {
//当observable发射时停止upstream
return upstream.takeUntil(observable);
}
即经过该转换器的转化,上游事件发生者会被另一个Observable限制发射。那么这个作为限制的Observable究竟是什么呢:
observable1
过滤出指定事件,这个可以实现到指定的Event时取消事件绑定。
private static <R> Observable<R> takeUntilEvent(final Observable<R> lifecycle, final R event) {
return lifecycle.filter(new Predicate<R>() {
@Override
public boolean test(R lifecycleEvent) throws Exception {
return lifecycleEvent.equals(event);
}
});
}
observable2
//R ActionEvent
private static <R> Observable<Boolean> takeUntilCorrespondingEvent(final Observable<R> lifecycle,
final Function<R, R> correspondingEvents) {
return Observable.combineLatest(
//拿一个
lifecycle.take(1).map(correspondingEvents),
lifecycle.skip(1),
new BiFunction<R, R, Boolean>() {
@Override
public Boolean apply(R bindUntilEvent, R lifecycleEvent) throws Exception {
return lifecycleEvent.equals(bindUntilEvent);
}
})
.onErrorReturn(Functions.RESUME_FUNCTION)
.filter(Functions.SHOULD_COMPLETE);
}
这个略微复杂,举例来说,如果你在onCreate中bindLifecycle,那Rxlifecycle会自动帮你在onDestroy里注销。onStart&onStop同理。所以代码就比较好理解,lifecycle.take(1).map(correspondingEvents)会找到对应的endEvent,然后与后续发射的Event对比,如果两者相等说明已经到了该结束的时刻了!
BehaviorSubject
BehaviorSubject是观察Lifecycle事件,在onCreate的时候它发射create event。我们把它跟真实的Observable绑定在一起,实现前面的takeUtil。当BehaviorSubject发射特定的事件时,真实的Observable退出。
// observer will receive the "one", "two" and "three" events, but not "zero"
BehaviorSubject<Object> subject = BehaviorSubject.create();
subject.onNext("zero");
subject.onNext("one");
subject.subscribe(observer);
subject.onNext("two");
subject.onNext("three");
可以看到,上述中observer只会收到one,two,three事件。而在RxActivity中,
@Override
@CallSuper
protected void onStart() {
super.onStart();
lifecycleSubject.onNext(ActivityEvent.START);
}
所以如果在onStart中绑定lifecycle事件,BehaviorSubject会收到从onStart开始的事件,这是不是跟前面的observable2结合起来看就一目了然了。
侵入性
Rxlifecycle具有很强的侵入性。从sample中也可以看到,你需要继承RxActivity,并且悲剧的是从前面截图可以看到,整篇代码在ide中飘黄,大概因为Rxjava2强制subscribe后返回的结果需要@CheckReturnValue。不过这也不能怪Rxlifecycle..毕竟取消了它的代码也还是会有警告- -
有关MVP
其实我们可以自己改造Rxlifecycle,我们知道,Presenter也是有生命周期的。最简单而言attachView() & detachView()。因此我们可以做如下改造:
//核心代码
@Override
@CallSuper
public void attachView(V view) {
super.attachView(view);
lifecycleSubject.onNext(PresenterEvent.ATTACH);
}
Autodispose
Uber的Autodispose和Rxjava2作用类似。但他很巧妙的解决了上面的问题。

当然,他的整体设计也更复杂一些。
ObservableSubscirbeProxy(single..类同)
它解决了Rxjava2中警告的问题。这里的subscribe不再是Observable.subscribe,而是在外面包了一层Subscribeproxy。简单来说,对于autoDispose而言,他其实打破了整个Rxjava subscribe to Observer的链路,而是完全由自己监管。

可以看到,将一个上游事件发射者转变为subscribeProxy
所以最终subscribe(observer)时,实际发生的是
AutoDisposeObservable<>(observableSource, scope()).subscribe(observer)
这里的observableSource是上游事件,scope是Maybe<?>。我们重点关注scope是什么:
autoDisposable(deferredResolvedLifecycle(checkNotNull(provider, "provider == null")));
AndroidLifecycleScopeProvider.from(this)
LifecycleEventsObservable
先插一句介绍一下这玩意。
接受Lifecycle作为参数一般是Activity...。它的内部有一个ArchLifecycleObserver,

我们可以把它看成一个发射LifecycleEvent的事件源。该事件源包含真实的Lifecycle,当它subscirbe(observer)时,会Lifecycle.add将它与lifecycle绑定起来。当observer监听到事件时,会调用actualObserver.onNext。
这边不理解可以先忽略,后面会再回过头来看。
LifecycleScopeProvider
生命周期的提供者。包含上述的LifecycleEventsObservable
关键代码
autoDisposable(deferredResolvedLifecycle(checkNotNull(provider, "provider == null")));
这里的deferredResolvedLifecycle返回了前面的Maybe<?>:
return Maybe.defer(new Callable<MaybeSource<? extends LifecycleEndNotification>>() {
@Override public MaybeSource<? extends LifecycleEndNotification> call() throws Exception {
E lastEvent = provider.peekLifecycle();
//outsideLifecycle
if (checkStartBoundary && lastEvent == null) {
LifecycleNotStartedException exception = new LifecycleNotStartedException();
Consumer<? super OutsideLifecycleException> handler
= AutoDisposePlugins.getOutsideLifecycleHandler();
if (handler != null) {
handler.accept(exception);
return Maybe.just(LifecycleEndNotification.INSTANCE);
} else {
throw exception;
}
}
E endEvent;
try {
endEvent = provider.correspondingEvents()
.apply(lastEvent);
} catch (Exception e) {
if (checkEndBoundary && e instanceof LifecycleEndedException) {
Consumer<? super OutsideLifecycleException> handler
= AutoDisposePlugins.getOutsideLifecycleHandler();
if (handler != null) {
handler.accept((LifecycleEndedException) e);
return Maybe.just(LifecycleEndNotification.INSTANCE);
} else {
throw e;
}
} else {
return Maybe.error(e);
}
}
return resolveScopeFromLifecycle(provider.lifecycle(), endEvent);
}
});
不懂这里为什么要Maybe.defer?
这里的lastEvent指的是上一个事件,endEvent指的是上一个事件对应的结束事件。。比如Create对应Destroy
/**
* @param lifecycle the stream of lifecycle events
* @param endEvent the target end event
* @param <E> the lifecycle event type
* @return a resolved {@link Maybe} representation of a given lifecycle, targeting the given event
*/
public static <E> Maybe<LifecycleEndNotification> resolveScopeFromLifecycle(
Observable<E> lifecycle,
final E endEvent) {
return lifecycle.skip(1)
.map(new Function<E, Boolean>() {
@Override public Boolean apply(E e) throws Exception {
return e.equals(endEvent);
}
})
.filter(IDENTITY_BOOLEAN_PREDICATE)
.map(TRANSFORM_TO_END)
.firstElement();
}
这段代码是不是在Rxlifecycle中似曾相识。。。废话,他也是得到与endEvent匹配的事件。这里看到provider.lifecycle()了吗,我们可以回到上面的LifecycleEventsObservable。当它被订阅的时候,就真正与Activity这种LifecycleOwner绑定了起来,当observer监听到生命周期事件并发生onStateChange时,会调用actualObserver.onNext。
扯了一大堆,结论就是scope返回了一个Observable,它只会在发生对应的endEvent时发出事件。
不得不感慨uber工程师设计的精妙。。

那我们再回过头来看最初的代码:
AutoDisposeObservable<>(observableSource, scope()).subscribe(observer)
-->
source.subscribe(new AutoDisposingObserverImpl<>(scope, observer));
AutoDisposingObserverImpl是一个很 有趣的类,它让scope被一个DisposableMaybeObserver订阅,当scope发出endEvent事件时,该observer会把mainDisposable的状态设置为DISPOSED,而当真实的observer收到事件时,如果发现mainDisposable已经为DISPOSED就不会处理接受到的真实事件。
我把整个过程过程了一张图,作为总结。
从上图可以看到,LifecycleScopeProvider包括LifecycleEventsObservable,后者与endEvent组合生成了一个叫scope()的事件发生器。当这个java source.subscribe(new AutoDisposingObserverImpl<>(scope, observer));发生时,scope向DisposableMaybeObserver订阅。
这时如果Lifecycle发出LifecycleEvent,因为ArchLifecycleObserver是一个LifecycleObserver,他可以监听到生命周期事件。并且传递给下流downStream,经过之前的串联运算符的过滤后到DisposableMaybeObserver就是真正的endEvent。可以看到顺理成章完成了我们希望达到的目的。
Why Not RxLifecycle?
挺有趣的,Rxlifecycle原作者写了一篇为什么不要使用rxlifecycle - -
他提出了以下几点原因并给出了自己的优化建议,当然有些个人觉得是他强迫症了- -
- 他认为自动化的生命周期检测有的时候会让人感到困扰,有的时候你的组件可能不在
activity里面,那你需要把lifecycle传递给他,并且寄希望于在正确的生命周期时间进行unsubscribe(这个正确的可能很难做到).比如你有一个adapter,它的数据来源于observable.关键在于你无法知道什么时候可以unsubscribe..因为你在adapter里没有地方给你生命周期函数去subscribe....当然你可以使用bindUntilEvent(),但是就削弱了rxlifecycle提供的功能 - 经常其实我们还是会手动去处理
subscription。比如adapter这个例子,可能我现在正在监听一个数据源,但是之后想监听另一个,那就需要把上一个取消掉。这个时候用户可能会感到很奇怪,为什么我们在一个地方手动ubsubscribe()同时又在另一个地方用了rxlifecycle - 还有前面提到过的问题,作者也进行了罗列。
作者还顺便略推荐了一把autodispose...至于他说的fewer restrictions on when it can be used in a stream我没怎么看懂。个人觉得可能想表达的是,Rxlifecycle使用了takeUtil运算符,直接就侵入了原有的流。而autoDispose还是完整的保留了原有的流。有知道的麻烦回复一下~
其实Rxlifecycle之前有较多问题是因为基于rxjava1,后来他迁到2.x版本后还是解决了很多问题的,比如也开始支持Single等等。
最后作者给出了一些优化建议与模式,我们开发可以参考:
- 手动处理
subscription。其实我们可以看到一种做法,把subscriptions存储在compositeSubscription(一个容器)。在合适的时候只要把compositeSubscription取消即可把全部订阅都取消。 - 对于类似
adapter的组件,他应该把自己的订阅抛到上层。例如adapter,就应该把subscription返回给activity让他去进行生命周期的管理。 -
kotlin天然的null优势,让开发者通过一行代码mySubscription?.unsubscribe()即可取消订阅
上面三种模式,最终希望达到同一个目的。但我们在使用的时候还是要注重业务场景,例如后两者明显是为Rxjava量身打造的,而前一种很适合用于单组件,例如前面提到的adapter,它就不会遇到后两者拥有的问题。
本文完结。有些问题还等待解决。