Android Jetpack 之 LiveData

Android Jetpack 之 LiveData

参考文章:

官方文档
“终于懂了“系列:Jetpack AAC完整解析(二)LiveData 完全掌握!

一、简介

官方定义

LiveData 是一种可观察的数据存储器类。与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵循其他应用组件(如 Activity/Fragment)的生命周期。这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。

使用 LiveData 具有以下优势

  • 确保界面符合数据状态
    LiveData 遵循观察者模式。当底层数据发生变化时,LiveData 会通知 Observer 对象。您可以整合代码以在这些 Observer 对象中更新界面。这样一来,您无需在每次应用数据发生变化时更新界面,因为观察者会替您完成更新。
  • 不会发生内存泄漏
    观察者会绑定到 Lifecycle 对象,并在其关联的生命周期遭到销毁后进行自我清理。
  • 不会因 Activity 停止而导致崩溃
    如果观察者的生命周期处于非活跃状态(如返回栈中的 Activity),则它不会接收任何 LiveData 事件。
  • 不再需要手动处理生命周期
    界面组件只是观察相关数据,不会停止或恢复观察。LiveData 将自动管理所有这些操作,因为它在观察时可以感知相关的生命周期状态变化。
  • 数据始终保持最新状态
    如果生命周期变为非活跃状态,它会在再次变为活跃状态时接收最新的数据。例如,曾经在后台的 Activity 会在返回前台后立即接收最新的数据。
  • 适当的配置更改
    如果由于配置更改(如设备旋转)而重新创建了 Activity 或 Fragment,它会立即接收最新的可用数据。
二、 接入
implementation 'androidx.lifecycle:lifecycle-livedata:2.2.0'
三、基本使用

以下说明使用 ViewModel+LiveData 方式

步骤一:创建LiveData实例

class NameViewModel : ViewModel() {
    val currentName: MutableLiveData<String> by lazy {
        MutableLiveData<String>()
    }
}

注意:请确保用于更新界面的 LiveData 对象存储在 ViewModel 对象中,而不是将其存储在 Activity 或 Fragment 中,原因如下:
1.避免 Activity 和 Fragment 过于庞大。现在,这些界面控制器负责显示数据,但不负责存储数据状态。
2.将 LiveData 实例与特定的 Activity 或 Fragment 实例分离开,并使 LiveData 对象在配置更改后继续存在。(比如Activity重建,还能有数据)

步骤二:创建Observer实例,实现onChanged()方法,用于接收源数据变化并刷新UI.

步骤三:LiveData实例使用observe()方法添加观察者,并传入LifecycleOwner。

步骤四:LiveData实例使用setValue()/postValue()更新源数据 (子线程要postValue())

注意:子线程改变值用postValue,因为在多线程中操作数据是不安全的,而postValue是通过synchronized关键字确保线程安全

  MyViewModel  viewModel = new ViewModelProvider(this).get(MyViewModel.class);
        //步骤三
        viewModel.stringLiveData.observe(this, new Observer<String>() {
        //步骤二
            @Override
            public void onChanged(String s) {
                Log.e("MainActivity",s+"----");
            }
        });
        
        textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //步骤四
                viewModel.stringLiveData.setValue("哈哈哈哈");    
            }
        });
四、 observeForever(Observer)

使用 observeForever(Observer) 方法在没有关联的 LifecycleOwner 对象的情况下注册一个观察者。在这种情况下,观察者会被视为始终处于活跃状态,因此它始终会收到关于修改的通知。您可以通过调用 removeObserver(Observer) 方法来移除这些观察者。

五、 高级用法
  • 转换只会在活跃生命周期里面进行

5.1 数据修改 - Transformations.map

  • 对存储在 LiveData 对象中的值应用函数,并将结果传播到下游
val userLiveData: LiveData<User> = UserLiveData()
val userName: LiveData<String> = Transformations.map(userLiveData) {
    user -> "${user.name} ${user.lastName}"
}

5.2 数据切换 - Transformations.switchMap

  • 与 map() 类似,对存储在 LiveData 对象中的值应用函数,并将结果解封和分派到下游。传递给 switchMap() 的函数必须返回 LiveData 对象,如以下示例中所示:。
private fun getUser(id: String): LiveData<User> {
  ...
}
val userId: LiveData<String> = ...
val user = Transformations.switchMap(userId) { id -> getUser(id) }
六、Fragment中liveData.observe(this)和liveData.observe(viewLifecycleOwner)的区别
liveData.observe(this) {
    // livedata 生命周期将与片段(Fragment)的整个生命周期(onCreate()开始、onDestroy()结束)相关联;
}

liveData.observe(viewLifecycleOwner) {
    // livedata 生命周期将与片段(Fragment)何时拥有(和失去)其 UI(onCreateView() 开始、onDestroyView()结束)相关联;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值