jetpack-LiveData&ViewModel学习

LiveData简介

LiveData一个具有生命周期的对象。他可以和Activity的生命生命周期绑定,可以监听对象的数据变化。

LiveData的优势

  1. 可监听数据的变化
  2. 没有内存泄露:LiveData绑定Lifecycle(AndroidX的Activity和Fragment都实现了Lifecycle)对象,并在其相关生命周期被破坏后自行清理。
  3. 没有因停止活动而崩溃:当界面失去焦点或销毁,此时异步网络请求回调完成。LiveData不必回调观察者
  4. 始终保持最新数据:这个要和第2条有关系,例如异步网络请求,返回数据设置给LiveData。在网络请求期间,界面切换到了后台,此时注册的LiveData观察值,并不会回调,当界面恢复到活动状态,立刻收到回调。
  5. 可以和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的setValuepostValue方法,没有完全暴露出来,每次还要写暴露方法,是不是很麻烦。可以使用提供的子类。

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
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值