我一直在使用Observables
库在我的代码中使用很多RxJava LiveData
转换为LiveDataReactiveStreams.fromPublisher()
。所以我想在RxJava Observable中添加一个扩展函数,以便轻松地将它们转换为LiveData
。
这些是我的扩展功能:
fun <T> Flowable<T>.toLiveData() : LiveData<T> {
return LiveDataReactiveStreams.fromPublisher(this)
}
fun <T> Observable<T>.toLiveData(backPressureStrategy: BackpressureStrategy) : LiveData<T> {
return LiveDataReactiveStreams.fromPublisher(this.toFlowable(backPressureStrategy))
}
fun <T> Single<T>.toLiveData() : LiveData<T> {
return LiveDataReactiveStreams.fromPublisher(this.toFlowable())
}
fun <T> Maybe<T>.toLiveData() : LiveData<T> {
return LiveDataReactiveStreams.fromPublisher(this.toFlowable())
}
fun <T> Completable.toLiveData() : LiveData<T> {
return LiveDataReactiveStreams.fromPublisher(this.toFlowable())
}
我的问题是:
P.S。
我是Kotlin的新手,所以我问这些问题。任何有用的东西将不胜感激。非常感谢你。
答案 0 :(得分:7)
我认为这是一个很好的主意。 LiveData
的一个示例优势是可以直接在数据绑定布局中使用它。假设您的视图模型中有:
val user: LiveData<User>
data class User(val firstName: String, val lastName: String)
在布局中,您可以直接绑定User
的属性:
android:text="${viewModel.user.firstName}"
您不能像这样在数据绑定中使用反应流。如果user
是Flowable<User>
,则引用${viewModel.user.firstName}
无效。
此外,如果您的活动或片段调用ViewDataBinding.setLifecycleOwner(LifecycleOwner)
,则数据绑定将为您处理生命周期(仅在活动状态下观察更改并在发生更改时更新视图):
binding.setLifecycleOwner(this)
将Completable
转换为LiveData<T>
的方法对我来说真的没有意义,因为它永远不会通知观察者任何事情,所以我会摆脱它。
从反应性流转换为实时数据时,需要考虑一些因素(就像我想resume a countdown after rotation时那样),但是我认为它们与您介绍的扩展功能无关,这些似乎确实可以他们的工作。这里要记住的问题是,当生命周期所有者从活动状态变为非活动状态时,PublisherLiveData
取消对流的订阅,并且当状态变为活动状态时,它将创建一个新的订阅,这意味着重新启动在许多情况下(我想这是流是“冷”的)流,而您可能想从旋转或其他配置更改后的位置恢复流。另一方面,如果流是“热”的,则在非活动状态期间将忽略排放。我认为即使您直接使用反应性流并手动处理生命周期,也必须解决此问题。但事实是,仅将反应流转换为LiveData
不足以解决此问题。
最好将那些方法记录为未处理错误状态,而错误状态必须在上游处理。另外,这可能是这些功能的改进之一-首先转换流以处理错误(例如,作为带有默认值的lambda参数)。另一种可能性是利用Result
(目前是实验性的)或类似的方法来封装成功或错误。
事后,关于我上面写的这部分内容:
从反应流转换为实时数据时,需要考虑一些因素,但我认为它们与您介绍的扩展功能无关。
我仍然认为它总体上是正确的,但是我不确定您是否实际上想在大多数情况下在实践中使用Single.toLiveData()
和Maybe.toLiveData()
。由于Maybe
和Single
正在对一次性操作进行建模,因此,当没有活动的观察者时,最好不要取消它,而在有新的活动的观察者时,必须重新启动它。相反,将其发布到某些MutableLiveData
并将Single
/ Maybe
放在onCleared
中可能很有用(我不确定是否可以将其封装在扩展函数中)。他们可能仍然有我暂时看不到的用途。
顺便说一句,您的Flowable.toLiveData()
已经在androidx.lifecycle:lifecycle-reactivestreams-ktx
artifact中。
这留下了Observable.toLiveData()
,我认为它应该和Flowable
一样有用。
答案 1 :(得分:3)
如果您想一起使用LiveData和Rx,那么您的解决方案就可以了。
如果您只想自动处理订阅,可以在Disposable上实现,如下所示:
private class LifecycleDisposable(obj: Disposable) :
DefaultLifecycleObserver, Disposable by obj {
override fun onStop(owner: LifecycleOwner) {
if (!isDisposed) {
dispose()
}
}
}
fun Disposable.attachToLifecycle(owner: LifecycleOwner) {
owner.lifecycle.addObserver(LifecycleDisposable(this))
}
并将其称为
Observable.just(1, 2, 3).subscribe().attachToLifecycle(this)
其中this
引用任何LifecycleOwner。
答案 2 :(得分:0)