LiveData
LiveData简介
LiveData一个具有生命周期的对象。他可以和Activity的生命生命周期绑定,可以监听对象的数据变化。
LiveData的优势
可监听数据的变化
没有内存泄露:
LiveData绑定Lifecycle(AndroidX的Activity和Fragment都实现了Lifecycle)对象,并在其相关生命周期被破坏后自行清理。没有因停止活动而崩溃:
当界面失去焦点或销毁,此时异步网络请求回调完成。LiveData不必回调观察者始终保持最新数据:
这个要和第2条有关系,例如异步网络请求,返回数据设置给LiveData。在网络请求期间,界面切换到了后台,此时注册的LiveData观察值,并不会回调,当界面恢复到活动状态,立刻收到回调。可以和Data Binding一起使用:
这里有个坑,Data Binding Compiler V1编译器,是不支持的LiveData配合使用的(只可以使用ObservableField来实现双绑定)。Data Binding Compiler V2后面已经支持和LiveData双向绑定功能
LiveData使用
自定义LiveData对象
class StockLiveData(symbol: String) : LiveData<String>() {
init {
// 设置默认值 这个value是LiveData的参数,记录他的值
value = symbol
}
override fun onActive() {
// 绑定生命周期
}
override fun onInactive() {
// 结束回调,也就是Activity或Fragment调用了onDestroy
}
}
注册LiveData数据观察者,可以发现observe传了一个this,这个this是实现了LifecycleOwner接口
// this 是一个Activity
StockLiveData("value").observe(this) {
Log.d("wyz","收到修改的值:$it")
}
如何修改LiveData的值呢?
- 直接调用LiveData的
setValue
方法,但是这个方法是通过protected
修饰,最好暴露一个修改方法。(注意setValue
方法必须在主线程调用,不然会报错,具体原因) - 上面说了
setValue
只能在主线程调用,那如果在子线程呢?LiveData已经帮们想好了postValue
方法
LiveData的子类
LiveData的setValue
和postValue
方法,没有完全暴露出来,每次还要写暴露方法,是不是很麻烦。可以使用提供的子类。
MutableLiveData
val title: MutableLiveData<String> by lazy {
MutableLiveData<String>("默认标题")
}
MediatorLiveData
MediatorLiveData是MutableLiveData子类,他和MutableLiveData的区别在于,他内部维护了个Map,他可以将多了个LiveData的合并在一起。举个例子:
考虑以下情形:我们有两个实例LiveData,让他们的名字 liveData1和liveData2,我们希望合并其排放量一个对象: mediatorLiveData。然后,liveData1并且liveData2将成为它的源,MediatorLiveData mediatorLiveData并且每次onChanged为它们中的任何一个调用回调时,我们在其中设置新值mediatorLiveData。
val liveData1 = MutableLiveData<String>()
val liveData2 = MutableLiveData<String>()
// 创建mediatorLiveData
val mediatorLiveData = MediatorLiveData<String>()
private fun testLiveData() {
// 做关联1
mediatorLiveData.addSource(liveData1) {
mediatorLiveData.value = it
}
// 做关联2
mediatorLiveData.addSource(liveData2) {
mediatorLiveData.value = it
}
mediatorLiveData.observe(this) {
// 这样不管是liveData1和liveData2数据发生改变,都会调用mediatorLiveData的数据改变
}
}
还有一种用途,例如上面的我只想liveData1数据改变10次后,就不在通知mediatorLiveData数据改变了,要怎么写呢?
mediatorLiveData.addSource(liveData1, object : Observer<String> {
var count = 0
override fun onChanged(t