LiveData的优势
- 确保界面符合数据状态:LiveData 遵循观察者模式。当底层数据发生变化时,LiveData 会通知 Observer 对象。您可以整合代码以在这些 Observer 对象中更新界面。
- 不会发生内存泄漏:观察者会绑定到 Lifecycle 对象,并在其关联的生命周期遭到销毁后进行自我清理。
- 不会因 Activity 停止而导致崩溃:如果观察者的生命周期处于非活跃状态(如返回栈中的 Activity),则它不会接收任何 LiveData 事件。
- 不再需要手动处理生命周期:界面组件只是观察相关数据,不会停止或恢复观察。LiveData 将自动管理所有这些操作,因为它在观察时可以感知相关的生命周期状态变化。
- 数据始终保持最新状态:如果生命周期变为非活跃状态,它会在再次变为活跃状态时接收最新的数据。
- 适当的配置更改:如果由于配置更改(如设备旋转)而重新创建了 Activity 或 Fragment,它会立即接收最新的可用数据。
- 共享资源:可以使用单例模式扩展 LiveData 对象以封装系统服务,以便在应用中共享它们。
LiveData使用
- 定义
private val normaLiveData1 = MutableLiveData()
- 赋值
normaLiveData1.value=“LiveDataValue”//UI线程
normaLiveData1.postValue(“LiveDataValue”)//非UI主线程
- 观察数据
normaLiveData1.observe(viewLifecycleOwner, Observer {
LogUtil.e(“观察到第一个值发生了变化”)
tv.text = it
})
- 无生命周期感知地观察数据,这种方式需要手动取消观察,否则会发生内存泄漏
val observer=Observer{
LogUtil.e(“观察到第一个值发生了变化”)
}
normaLiveData1.observeForever(observer)
//在合适的生命周期移除观察
normaLiveData1.removeObserver(observer)
- 转换 LiveData
private val transLiveData= Transformations.map(normaLiveData1){
“$it -----转换”
}
- 合并多个 LiveData
private val mediatorLiveData = MediatorLiveData()
mediatorLiveData.addSource(normaLiveData1){
mediatorLiveData.value=“合并后的值: i t − − − it--- it−−−{normaLiveData2.value}”
}
mediatorLiveData.addSource(normaLiveData2){
mediatorLiveData.value=“合并后的值: n o r m a L i v e D a t a 1. v a l u e − − − {normaLiveData1.value}--- normaLiveData1.value−−−it”
}
- LiveData结合room、协程使用(下文)
kotlin数据流 Flow
Flow数据流以协程为基础构建,可提供多个值。从概念上来讲,数据流是可通过异步方式进行计算处理的一组数据序列,有点像RxJava。
Flow的使用
- 创建Flow
val flow = flow {
emit(“value1”)
emit(“value2”)
delay(1000)
emit(“value3”)
}
val flow = flowOf(“value”)
val flow = listOf(1, 2, 3).asFlow()
- 收集Flow----collect()
由于 collect 是挂起函数,因此需要在协程中执行
scope.launch {
flow.collect {
LogUtil.e(it)
}
}
- 转换Flow----map()
flowOf(1, 2, 3).map {
“第$it 个”
}.collect {
LogUtil.e(it)
}
- 过滤Flow----filter()
flowOf(1, 2, 3).filter {
it > 1
}.collect {
LogUtil.e(it)
}
- 合并Flow
zip操作符会把 flow1 中的一个 item 和 flow2 中对应的一个 item 进行合并,如果 flow1 中 item 个数大于 flow2 中 item 个数,合并后新的 flow 的 item 个数 = 较小的 flow 的 item 个数
val flow1 = flowOf(1, 2, 3, 4, 5)
val flow2 = flowOf(“一”, “二”, “三”, “四”, “五”, “六”)
flow1.zip(flow2) { a, b ->
“ a − − − a--- a−−−b”
}.collect {
LogUtil.e(it)
}
combine合并时,每次从 flow1 发出新的 item ,会将其与 flow2 的最新的 item 合并
val flow1 = flowOf(1, 2, 3, 4, 5).onEach { delay(1000) }
val flow2 = flowOf(“一”, “二”, “三”, “四”, “五”, “六”).onEach { delay(500) }
flow1.combine(flow2) { a, b ->
“ a − − − a--- a−−−b”
}.collect {
LogUtil.e(it)
}
- 捕获异常----catch()
flow {
emit(1)
emit(1 / 0)
emit(2)
}.catch {
it.printStackTrace()
}.collect {
LogUtil.e(it)
}
- 线程切换----flowOn()
withContext(Dispatchers.IO){
flowOf(1, 2, 3, 4).onEach {
//受到下面最近的flowOn控制-Main
LogUtil.e(“init—KaTeX parse error: Expected 'EOF', got '}' at position 33: …read().name}") }̲.filter { //受到下…{Thread.currentThread().name}”)
it > 1
}.flowOn(Dispatchers.Main).map {
//受到下面最近的flowOn控制-IO
LogUtil.e(“map— T h r e a d . c u r r e n t T h r e a d ( ) . n a m e " ) " 第 {Thread.currentThread().name}") "第 Thread.currentThread(