Jetpack之LiveData

一、前言

LiveDataAndroid中用来进行数据监听的类。由于一些限制,现在官方推荐使用Flow进行数据监听。在ktx拓展包中,使用LiveData.asFlow()可以很方便的将LiveData转换为FlowFlow.asLiveData()也可以很方便的将Flow转换为LiveData

二、特点

LiveData通常在ViewModel里面创建,这是因为以下原因。

  • 确保系统不会从 Activity 或 Fragment 的 [onResume()](https://developer.android.com/reference/android/app/Activity?hl=zh-cn#onResume()) 方法进行冗余调用。
  • 确保 Activity 或 Fragment 变为活跃状态后具有可以立即显示的数据。一旦应用组件处于 STARTED 状态,就会从它正在观察的 LiveData 对象接收最新值。只有在设置了要观察的 LiveData 对象时,才会发生这种情况。

三、添加依赖

implementation 'androidx.lifecycle:lifecycle-livedata:2.4.0'
// or
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.4.0'

四、初步使用示例

创建

class NameViewModel : ViewModel() {

    // Create a LiveData with a String
    val currentName: MutableLiveData<String> by lazy {
        MutableLiveData<String>()
    }

    // Rest of the ViewModel...
}

观察

class NameActivity : AppCompatActivity() {

    // Use the 'by viewModels()' Kotlin property delegate
    // from the activity-ktx artifact
    private val model: NameViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Other code to setup the activity...

        // Create the observer which updates the UI.
        val nameObserver = Observer<String> { newName ->
            // Update the UI, in this case, a TextView.
            nameTextView.text = newName
        }

        // Observe the LiveData, passing in this activity as the LifecycleOwner and the observer.
        model.currentName.observe(this, nameObserver)
    }
}

赋值

model.currentName.value = anotherName //该方式不可以在子线程使用
//or
model.currentName.postValue(anotherName) //该方式可以在子线程使用

LiveData中只能进行数据监听而不能进行更改,更改的话只能使用MutableLiveData。为了遵从设计原则,可以使用以下范例:

    private val _liveData: MutableLiveData<String> by lazy {
       MutableLiveData<String>()
    }
    val liveData: LiveData<String> = _liveData

需要注意的是,倘若LiveData创建的时候如果有值会在添加监听后立刻触发监听

五、Transformations

Lifecycle 软件包会提供 Transformations 类。该类会对LiveData进行一个辅助操作。其中主要会用到map(LiveData)switchMap(LiveData)。示例如下(Transformations源码也有示例):

val userLiveData: LiveData<User> = UserLiveData()
val userName: LiveData<String> = Transformations.map(userLiveData) {
    user -> "${user.name} ${user.lastName}"
}
private fun getUser(id: String): LiveData<User> {
  ...
}
val userId: LiveData<String> = ...
val user = Transformations.switchMap(userId) { id -> getUser(id) }

主要用途是当其中一个LiveData进行改变时候会触发其于依赖于该LiveDataLiveData。这两个函数的唯一区别就是map(LiveData)返回普通类型,switchMap(LiveData)返回LiveData类型。

六、MediatorLiveData

该类可以进行数据源的合并,以下为MediatorLiveData源码中的示例:

  LiveData  liveData1 = ...;
   LiveData  liveData2 = ...;
  
   MediatorLiveData  liveDataMerger = new MediatorLiveData<>();
   liveDataMerger.addSource(liveData1, value -> liveDataMerger.setValue(value));
   liveDataMerger.addSource(liveData2, value -> liveDataMerger.setValue(value));
   

MediatorLiveData实现监听的话,其依赖的数据源任何一个改变都会触发该对象的监听。

七、liveData{}

下面演示一种写法(源自androidx.lifecycle.LiveDataScope源码,源码中有更多示例):

val data : LiveData<Int> = liveData {
    delay(3000)
    emit(3)
}

该写法需要依赖于ktx拓展,主要是使用协程进行编写的。这种写法表示如果在非活动状态(也就是生命周期Start和Resume之外的时候)会在3秒后取消。当变成活动时候会重新计算。

如果不需要延时可以写成下面方式:

val data : LiveData<Int> = liveData {
    val queryUserCount = query()
    emit(queryUserCount)
}

八、Livedata建立observe时,抛Cannot add the same observer with different lifecycles的问题

参考链接:https://blog.csdn.net/weixin_36762615/article/details/106719262?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-106719262-blog-102664893.pc_relevant_multi_platform_whitelistv3&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-106719262-blog-102664893.pc_relevant_multi_platform_whitelistv3&utm_relevant_index=2

推测是因为ViewModel里面持有静态变量导致无法销毁,后面再次进入时候又一次添加了observe导致的该问题。但是没有测试。模拟的方式是,在onstart里面进行初始化,不过该方式也未实践

九、参考链接

  1. LiveData 概览
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值