前言
LiveData、Kotlin Flow和RxJava三者都属于可观察的数据容器类
RxJava
RxJava是基于观察者模式去实现的响应式编程,可以使用多种操作符进行组合将各种复杂的请求简单化
其优点:
- 异步。RxJava是基于异步操作的框架,常用的应用场景有网络访问、数据解析等
- 链式操作。RxJava提供了当前最主流的链式编程,其方式类似于构建者模式
- 线程切换。RxJava提供了线程切换的功能,可以任意的在UI线程和工作线程中切换
- 丰富的操作符。RxJava提供了丰富的操作符,简化了我们对方法或数据的操作
- 背压策略。RxJava针对网络访问的高并发性,提供了背压的策略进行处理
其缺点:
- RxJava使用简单,但门槛太高,Android开发者如果没有深入了解过函数式相关的知识,很容易出现写的代码期望结果不一致,或容易犯错误
LiveData
LiveData由Google自2017年推出,LiveData相对RxJava出现较晚,相当于轻量版的RxJava
其优点:
- LiveData使用简单,更加轻量,上手门槛低,众多开发者可以很轻松的上手LiveData,代码也更加容易理解
- LiveData和DataBinding这两套支持库能非常方便的帮助开发人员实现数据传递与数据绑定上的痛点
其缺点:
- LiveData的操作符不够强大,在处理复杂数据流时有些捉襟见肘
- LiveData存在粘性消息问题
- LiveData无法处理异常
- LiveData不会像RxJava那样处理完数据后自动结束,而是像Subject一样,对数据的监听永无结束,除非手动去结束订阅
- LiveData不支持线程切换,所有数据转换都将在主线程上完成,有时需要频繁更改线程,面对复杂数据流时处理起来比较麻烦
1、LiveData缺少丰富的操作符,为了弥补这个缺点,LiveData提供Transformations工具类中的map,switchMap等操作符
val source: LiveData<Int> = MutableLiveData<Int>()
val transfor: LiveData<String> = Transformations.map(source) {
it.toString()
}
2、LiveData本身的设计理念比较简单,无法像RxJava那样发送数据和异常,在LiveData中处理异常的做法
class Result {
data class Success(val data: Foo) : Result()
data class Error(val error: Throwable) : Result()
}
results: LiveData<Result>
3、LiveData不支持链式操作
RxJava中简单的链式逻辑
fun allPosts(): Observable<Post> =
allUsers()
.map { user -> user.id }
.flatMap { userId -> userPosts(userId) }
LiveData中只能用命令式的写法完成
fun allPosts(): LiveData<Post> {
val userIds = Transformations.map(allUsers()) { user: User? ->
user!!.id
}
return Transformations.switchMap(userIds) { id: String? ->
userPosts(id!!)
}
}
Flow
Flow是官方提供的,目前是Google主推的数据流框架
其优点:
- Flow支持协程
- Flow支持线程切换、背压
- Flow入门的门槛很低,操作符简单清晰,学习成本低
- Flow更好的和其他Jetpack组件的配合,可以通过操作符转化为LiveData,与Room等第三方框架配合也更加方便
- Flow与 RxJava 相比,对生命周期的支持更加简单
其缺点:
- Flow仅Kotlin使用,目前仍然有很多项目依然使用Java
总结
- RxJava:适合复杂化的场景,要求开发者对框架内部实现有一定了解
- LiveData:适合简单化的场景,数据交互和UI交互单一的场景
- Flow:适合Kotlin编程使用,功能丰富,要求开发者熟悉掌握用法,近似于Kotlin版的Rxjava