1. LiveData是什么
LiveData 是 Android Jetpack 提供的一种具有生命周期感知能力的可观察数据容器。
数据发生变化时,它会通知处于活跃状态(STARTED、RESUMED)的观察者更新 UI,并且在观察者生命周期结束后自动移除观察关系。
LiveData 的生命周期感知
LiveData 不会无条件通知观察者。
当 Activity 处于活跃状态时,通常是:
STARTED
RESUMED
LiveData 才会向它发送数据。
当 Activity 被销毁后,LiveData 会自动移除对应观察者,从而降低:
- 内存泄漏风险
- 已销毁页面仍然更新 UI 的风险
- 手动取消订阅的工作量
面试回答:
LiveData 的主要优势是生命周期感知。它只通知处于活跃状态的观察者,并且在 LifecycleOwner 销毁后自动移除观察关系。
与 ViewModel 常常配合使用
ViewModel 负责保存和管理界面状态,LiveData 负责在状态变化时通知 UI。ViewModel 可以在配置变更期间继续存在,因此两者配合可以减少 Activity 或 Fragment 重建导致的数据丢失。
LiveData 优点:
- 生命周期感知
只通知活跃的 Activity 或 Fragment。 - 自动更新 UI
数据变化时自动触发观察者。 - 减少内存泄漏风险
ifecycleOwner 销毁后自动移除观察关系。 - 配合 ViewModel 保存状态
可以应对屏幕旋转等配置变更。 - 解耦 UI 与数据逻辑
Activity 只负责显示,ViewModel 负责处理状态。
2. 案例
第一步 添加依赖
`app/build.gradle.kts` 中 `dependencies` 加入
dependencies {
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.11.0")
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.11.0")
}
第二步 创建界面
activity_main.xml 中
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:padding="24dp">
<TextView
android:id="@+id/tvCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:textSize="48sp" />
<Button
android:id="@+id/btnAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="增加" />
</LinearLayout>
- 一个显示数字的
TextView - 一个增加数字的
Button
第三步 创建 ViewModel
新建 CounterViewModel.kt kotlin 类
package com.example.livedatademo
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class CounterViewModel : ViewModel() {
// 只有 ViewModel 内部可以修改
private val _count: MutableLiveData<Int> =
MutableLiveData<Int>(0)
// Activity 只能观察,不能直接修改
val count: LiveData<Int> = _count
fun increase() {
val currentCount = _count.value ?: 0
_count.value = currentCount + 1
}
}
这里出现了两个重要类型
MutableLiveData<Int> 表示其中的数据能观察,也可以被修改。
LiveData<Int> 表示外部只能观察数据,不能修改数据。
官方推荐在 ViewModel 内部保存 MutableLiveData,向界面公开只读的 LiveData,从而避免 Activity 或 Fragment 随意修改状态。
这种写法称为 backing property(后备属性):
private val _count = MutableLiveData(0)
val count: LiveData<Int> = _count
变量前面的下划线 _count 通常表示“内部可修改版本
后备属性的本质是封装可变性(面向对象中的封装),明确状态的所有权和修改边界。ViewModel 内部持有可变的
MutableLiveData,对外只暴露只读的LiveData,使 ViewModel 成为该状态的唯一修改者。这样 UI 层只能观察状态和表达操作意图,不能直接修改状态。最终可以降低 UI 层与状态实现之间的耦合,统一状态修改入口,并保证数据的一致性(统一只能在内部修改,暴露修改方法而不是可修改对象,防止外部直接修改破坏内部设立的规则)和可维护性。
两种数据更新方式
liveData.setValue() / value =:必须在主线程调用,会立即更新值并通知活跃观察者。
liveData.postValue():可以在后台线程调用,它会把更新任务提交到主线程,之后再通知观察者。最终还是会在主线程操作
第四步 在Activity中观察LiveData
修改 MainActivity.kt
package com.example.livedatademo
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
private val viewModel: CounterViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val countText = findViewById<TextView>(R.id.tvCount)
val addButton = findViewById<Button>(R.id.btnAdd)
// 观察 LiveData, 传入的是lifecycleOwner 的
viewModel.count.observe(this) { count ->
countText.text = count.toString()
}
// 点击按钮时,让 ViewModel 修改数据
addButton.setOnClickListener {
viewModel.increase()
}
}
}
核心代码是:
viewModel.count.observe(this) { count ->
countText.text = count.toString()
}
它表示:
当
count的值发生变化时,自动执行代码块并刷新 TextView。
LiveData 是生命周期感知的数据容器,只会在 Activity 或 Fragment 处于活跃状态时通知观察者;活跃状态通常指STARTED或RESUMED。当对应生命周期被销毁时,观察关系也会自动清理。
1万+

被折叠的 条评论
为什么被折叠?



