LiveData VS RxJava
本文比较了LiveData
和RxJava
在概念上的不同。
在看LiveData
官方文档时,我第一反应是——这是一个自带生命周期的类似RxJava的轮子。
我一开始把它看做RxJava来用,在使用一段时间后,LiveData总是让我觉得别扭。
问题就在于这两个概念实际上不太一样。
-
LiveData 是一个 holder 而不是 steam。它存储的是最新一个value,当有观测者观测时总是会获得这个最新的数据。
LiveData is essentially just like
BehaviorRelay
. It is a data holder that allows subscribers. But it also has an active/inactive state depending on number of current subscribers, so it’s kinda likereplay(1).publish().refCount()
. So, uh,RxReplayingShare
. -
另外一个不一样的线程模型。RxJava提供了一套简洁的线程切换方法,而LiveData所有操作都运行于主线程。
-
LiveData 会根据LifecycleOwner,自动管理subscriber的生命周期,RxJava则不会。
-
LiveData 只提供了
Transformations.map
、Transformations.switchMap
这两种操作符,远没有RxJava灵活。使用上也不支持链式调用。tips:可以使用Kotlin的扩展函数优化下fun <X, Y> LiveData<X>.map(transform: (x: X) -> Y): LiveData<Y> {
return Transformations.map(this) {
return@map transform(it)
}
}
fun <X, Y> LiveData<X>.switchMap(transform: (x: X) -> LiveData<Y>): LiveData<Y> {
return Transformations.switchMap(this) {
return@switchMap transform(it)
}
} -
从学习曲线上来讲,LiveData对新人更友好(这里可能是先学习过RxJava,有了流式的思想基础后再来学习LiveData造成的错觉。)
在 Twitter 上看到 @chrisbanes 提供的一种 LiveData 实践思路。
- LiveData 作为 UI 前端的数据展示层
- RxJava 作为 后端的 network 请求层
而 Google 官方提供的 Demo 中,是直接让Retrofit 网络请求返回 LiveData。
两者相比,我觉得还是@chrisbanes的实践更合理。为什么这么说呢?
-
LiveData 不适合作为 network 请求的返回值。
It’s weird to me to expose an HTTP request as live data because it really isn’t. I would think you would always have some intermediary class which allowed for things like refreshing the HTTP data and updating the existing
LiveData
.因为大部分的 network 请求都是一次性的(one-shot),而使用 LiveData 给人的感觉是数据可能会在之后更新。那么更适合的场景其实是LiveData 和数据库(Room)配合
-
利用 LiveData 的自动 clear 特性,管理RxJava 的 subscriptions,消除了RxJava 内存泄露的可能。
-
能利用 RxJava 简洁的线程切换的能力。
至于 RxJava Stream 和 LiveData 之间的互相转换可以使用LiveDataReactiveStreams
Author: deskid
Link: https://deskid.github.io/2017/08/07/LiveData-vs-Rxjava/
License: 知识共享署名-非商业性使用 4.0 国际许可协议