使用Kotlin扩展功能将RxJava Observables转换为实时数据 [英] Convert RxJava Observables To Live Data With Kotlin Extension Functions
问题描述
我一直在使用LiveDataReactiveStreams.fromPublisher()
库在我的代码中使用大量RxJava Observables
转换为LiveData
.因此,尽管我在RxJava Observable中添加了扩展功能,以轻松将其转换为LiveData
.
I've been using alot of RxJava Observables
converted to LiveData
in my code using LiveDataReactiveStreams.fromPublisher()
library. So I though of adding an extension function to the RxJava Observable to easily convert them to 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的新手,所以我在问这些问题.任何有帮助的将不胜感激.非常感谢.
I'm new to Kotlin and so I am asking these question. Anything helpful would be appreciated. Thank you very much.
推荐答案
我认为这是一个不错的主意. LiveData
的一个示例好处是可以直接在数据绑定布局中使用它.假设您的视图模型中有:
I think this is a pretty good idea. An example benefit of LiveData
is the ability of using it directly in your data-binding layouts. Let's say in your view-model you have:
val user: LiveData<User>
data class User(val firstName: String, val lastName: String)
在布局中,您可以直接绑定User
的属性:
in your layout you can bind the properties of the User
directly:
android:text="${viewModel.user.firstName}"
您不能像这样在数据绑定中使用反应流.如果user
是Flowable<User>
,则引用${viewModel.user.firstName}
将不起作用.
You can't use reactive streams in data-binding like this. If user
was Flowable<User>
, referencing ${viewModel.user.firstName}
wouldn't work.
Furthermore, data-binding will handle the lifecycle for you (observing changes only in active state and updating the view when changes happen) if your activity or fragment calls ViewDataBinding.setLifecycleOwner(LifecycleOwner)
:
binding.setLifecycleOwner(this)
将Completable
转换为LiveData<T>
的方法对我来说真的没有意义,因为它永远不会通知观察者任何事情,所以我会摆脱它.
The one for converting Completable
to LiveData<T>
doesn't really make sense to me, because it will never notify the observer about anything, so I'd just get rid of it.
从反应式流转换为实时数据时,有一些注意事项(例如我想 PublisherLiveData
取消对该流的订阅,并且当状态变为活动时,它将创建一个新的订阅,这意味着在许多情况下重新启动流(我想这是如果流为冷"的话),而您可能想从旋转或其他配置更改后的位置恢复该流.另一方面,如果流是热"的,则在非活动状态期间将忽略排放.我认为即使您直接使用反应性流并手动处理生命周期,也必须解决此问题.但事实是,仅将反应流转换为LiveData
不足以解决此问题.
There are some considerations when converting from reactive streams to live data (like I had when I wanted to resume a countdown after rotation), but I don't think they are related to the extension functions you presented, those seem to do their job. The issue to keep in mind here is that when the lifecycle owner moves from active to inactive state, PublisherLiveData
cancels the subscription to the stream, and when the state changes to active, it will create a new subscription, which means restarting the stream in many cases (I guess that is if the stream is "cold"), while you probably want to resume the stream from where it was after rotation or other configuration changes. If the stream was "hot" on the other hand, emissions get ignored during the inactive state. I think this problem has to be addressed even if you used reactive streams directly and handled life cycle manually. But the thing is that simply converting reactive streams to LiveData
isn't enough to solve this problem.
最好将那些方法记录为未处理错误状态,而错误状态必须在上游处理.另外,这可能是这些功能的改进之一-首先转换流以处理错误(例如,作为带有默认值的lambda参数).另一种可能性是利用 Result
(目前处于实验状态),或者类似的方法来封装成功或失败.
It's good to document those methods as not handling the error state, which has to be handled upstream. Alternatively, that could be one of the improvements for these functions - transforming the stream first to handle errors (as a lambda parameter with a default for example). Another possibility would be to utilize Result
(experimental at the moment), or something similar to encapsulate the success or error.
事后,关于我上面写的这部分内容:
As an afterthought, regarding this part that I wrote above:
从反应流转换为实时数据时,需要考虑一些因素,但我认为它们与您介绍的扩展功能无关.
There are some considerations when converting from reactive streams to live data, but I don't think they are related to the extension functions you presented.
我仍然认为它总体上是正确的,但是我不确定您是否实际上想在大多数情况下在实践中使用Single.toLiveData()
和Maybe.toLiveData()
.由于Maybe
和Single
正在对一次性操作进行建模,因此,当没有活动的观察者时,最好不要取消它,而一旦有新的活动的观察者,则必须重新启动它.相反,将其发布到某些MutableLiveData
并将Single
/Maybe
放置在onCleared
中可能有用(我不确定可以将其封装在扩展功能中).他们可能仍然有我目前看不到的一些用途.
I still think it holds true in general, however I'm not sure if you actually want to use Single.toLiveData()
and Maybe.toLiveData()
in practice most of the time. Since Maybe
and Single
are modeling one-time operations, then it may be preferable not to cancel it when there are no active observers and have to re-start it once there are new active observers. Instead, posting to some MutableLiveData
and disposing the Single
/Maybe
in onCleared
might be useful (I'm not sure that can be encapsulated in an extension function). They still may have some use that I simply don't see at the moment.
顺便说一句,您的Flowable.toLiveData()
已经在 androidx.lifecycle:lifecycle-reactivestreams-ktx
工件.
By the way, your Flowable.toLiveData()
is already in the androidx.lifecycle:lifecycle-reactivestreams-ktx
artifact.
这留下了Observable.toLiveData()
,我认为它应该和Flowable
一样有用.
This leaves the Observable.toLiveData()
, which I think should be just as useful as Flowable
one.
这篇关于使用Kotlin扩展功能将RxJava Observables转换为实时数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!