RxJava 是 Android 开发中的一件神器,但我们在 Activity 或 Fragment 里使用 RxJava 的时候要注意,没在恰当时机执行 Dispose 或终止 Observable 的话会导致内存泄漏。下面这段代码中,Consumer 匿名内部类持有 Activity 的引用,当 Activity 销毁时 Observable 并没有被中止或切断与 Observer 的联系(未 Dispose),所以就造成了内存泄漏。
Observable.interval(0, 2, TimeUnit.SECONDS) .subscribeOn(Schedulers.computation()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Consumer<Long>() { @Override public void accept(Long n) throws Exception { } });要避免这种情况的话,我们可以使用 Rx 官方提供的 Dispose 方法来在 Activity 销毁时手动切断 Observable 与 Observer 的联系(但是 Observable 还会继续发射数据):
private Disposable disposable;@Overridepublic void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) { super.onCreate(savedInstanceState, persistentState); disposable = Observable.interval(0, 2, TimeUnit.SECONDS) .subscribeOn(Schedulers.computation()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Consumer<Long>() { @Override public void accept(Long n) throws Exception { } });}@Overrideprotected void onDestroy() { super.onDestroy(); disposable.dispose();}这样写的体验是割裂的,你需要保存一堆 Disposable 的引用(当然你也可以使用 CompositeDisposable),然后在销毁时再「手工进行」Dispose。
探索有没有更优雅些的办法呢?答案是有的。在 Rx 官方提供的一些操作符中可以让我们提前中止 Observable 与 Observer 的联系,例如 TakeUtil 操作符:

假设Observable.takeUtil(ObservableB).subscribe(Observer)。当 ObservableB 发射第一个数据时,Observable 立刻被 Complete,同时立刻调用了 Observer 的 onComplete() 方法,观察结束后立刻释放对 Observer 的引用。
于是,脑洞大开的我们可以创建一个如下的变换操作符:
public BindLifecycleTransformer<T> implements ObservableTransformer<T, T> { private final BehaviorProcessor<Integer> lifecycleBehavior; public BindLifecycleObservableTransformer(@NonNull BehaviorProcessor<Integer> lifecycleBehavior) { this.lifecycleBehavior = lifecycleBehavior; } @Override public ObservableSource<T> apply(Observable<T> upstream) { return upstream.takeUntil( lifecycleBehavior.skipWhile(new Predicate<Integer>() { @Override public boolean test(@LifecyclePublisher.Event Integer event) throws Exception { return event != LifecyclePublisher.ON_DESTROY_VIEW && event != LifecyclePublisher.ON_DESTROY && event != LifecyclePublisher.ON_DETACH; } }).toObservable() ); }}接下来只要在 Activity 里创建一个用于记录当前所在生命周期的 LifecycleBehavior,然后就可以使用 compose(new BindLifecycleObservableTransformer(lifecycleBehavior)) 来绑定你的 Observable 到 Activity 的生命周期上了。
但是这样还是需要手动维护个 LifecycleBehavior。有没有办法连 LifecycleBehavior 都不写呢?答案依然是有的。
我们可以通过一个独立的 HeadlessFragment 来维护 LifecycleBehavior,然后想监听哪个 Activity 或 Fragment 的生命周期的话,只要将 HeadlessFragment 插入其中就行了,FragmentManager 会主动同步 HeadlessFragment 与父 Activity/Fragment 之间的生命周期。
RxLifecycle我们将上述的工作封装成了一个开源库 RxLifecycle ⇦猛戳,你可以在其中查阅上面提到的所有代码。它允许你仅用一句话绑定你的 Observable 到 Activity/Fragment 的生命周期上:
Observable.interval(0, 2, TimeUnit.SECONDS) .compose(RxLifecycle.bind(MainActivity.this).<Long>withObservable()) .subscribeOn(Schedulers.computation()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Consumer<Long>() { @Override public void accept(Long n) throws Exception { } });我们在仓库中还提供了个 DEMO,以便详细介绍 RxLifecycle 的全部功能。

作者:nekocode
出处:https://zhuanlan.zhihu.com/p/24992118