RxAndroid,事件总线和活动生命周期

时间:2017-01-13 20:55:06

标签: android rx-java rx-android activity-lifecycle otto

我发现一些文章谈论RxJava / RxAndroid如何取代事件总线(例如otto

第一篇文章的引用:

  

来自Square的Otto在前几天被正式弃用。在Android世界中,我们现在可以为“EventBusses死了很长的RxJava”而欢呼。

我有一件事我不在了:

事件总线的一个好处是它们对Activity生命周期有很大的帮助,因为你不需要手动管理注册/取消注册回调(从而避免内存泄漏)

示例流程:

  • 活动订阅获取歌曲的事件(比如SongsAvailableEvent)
  • 我们要求歌曲(我们提出网络请求)
  • 我们在请求中更改设备的方向
  • 活动终止并且构建了一个新活动,也订阅了SongsAvailableEvent
  • 新活动获取事件并更新用户界面,旧的活动(现在已经死亡)没有得到事件(耶!)

上面的文章看起来这个流程已经解决了#34;通过RxAndroid / RxJava,但是使用Rx时,您仍需要在更改设备的方向时手动订阅/取消订阅Observable。而且,如果我想"重复使用"在一个Observable中提出的请求,我需要以某种方式坚持它,以便我将在新的Activity中订阅相同的Observable(我不太确定如何做到这一点,但这不是重点:))。

我的问题是:这个问题是否很容易用纯RxAndroid / RxJava解决,或者我是否仍然需要使用事件总线/扩展Rx使用类似RxLifecycle之类的东西(由于我不管理这会使事情变得复杂)我在表达层的Observables)?

2 个答案:

答案 0 :(得分:0)

您的活动的onDestroy总是可以取消订阅。

至于使工作重用请求 - 查看Loaders和LoaderManager。 EventBus和RxJava解决这个问题从来都不需要。

答案 1 :(得分:0)

我想冒昧地说,在链中的某个点上,Observable必须与某些Android平台对象的生命周期相关联,例如Activity。此外,因为您没有将其作为部分解决方案提及,我假设您正在避免使用保留的碎片。如果您仅在活动中创建并保持对Observable的引用,则在运行中请求的结果不可能在销毁活动后继续存在并自动订阅新活动。此外,在某些时候,无论是在方向更改期间,还是在网络请求中间的活动结束时,如果没有取消订阅,Observable将泄漏对活动的引用(通过其subscribe()回调)活动onDestroy()

我发现RxLifecycle易于使用。我的基础Activity类有一个方法:

public <T> Observable.Transformer<T,T> bindLifecycleOnMainThread() {
    return o -> o.compose(lifecycleProvider.bindToLifecycle())
        .observeOn(AndroidSchedulers.mainThread());
}

lifecycleProvider是根据RxLifecycle的说明创建的,具体取决于您创建提供程序的方式。此特定实现使用bindToLifecycle()而不是指定显式生命周期事件,因此其使用是上下文的。在onResume期间调用它会使其在onPause结束。在onStart期间调用它会使其在onStop结束。其他时间调用它将导致它在onDestroy结束。由于此订阅将更新UI,因此只能在UI线程上观察它。

然后可以在Activity中使用,如下所示:

yourObservable.compose(bindLifecycleOnMainThread())
    .subscribe(event -> handleEvent(event));

现在,这个观察源从何而来?好吧,仍然没有魔法,如果你想让一个Observable比Activity更长寿命,那就意味着Observable必须由一个比Activity活动更久的组件持有。有许多方法可以做到这一点,但您的特定用例很好地映射到ViewModel框架中包含的新Android Architecture库。如果您要使用ViewModel,您的ViewModel将有一个开始网络请求的方法,并且会有PublishSubjectPublishRelay发出SongsAvailableEvent个对象(尽管我建议将它暴露给您的活动仅为Observable<SongsAvailableEvent>,而不是主题,以获得良好的封装!)。您的ViewModel将进行网络呼叫并将结果转发给您的主题。

最后,您的Activity在创建时将立即从ViewModel注册表获取其ViewModel并订阅ViewModel公开的Observable<SongsAvailableEvent>(主题/中继),然后将其绑定到Activity&# 39; s生命周期,如上例所示。 ViewModel将在Activity的任何方向更改后继续存在,因此observable也将如此。 Observable将永远不会尝试将事件传递给被破坏的Activity,新的Activity将立即开始侦听事件。

我认为这种策略可以促进良好的封装,因为Activity不关心网络请求的制作方式,也不关心如何创建源Observable。 Activity操作Observable的唯一方法是选择接收事件时发生的事情,并将订阅绑定到Activity的生命周期。

这可以通过编写你的Observable来无休止地调整和改进,但这应该让你顺利。