LiveData #
一、LiveData概述 #
LiveData是一种可观察的数据存储器类,具有生命周期感知能力。LiveData确保只有处于活跃状态的组件才会收到数据更新通知。
1.1 LiveData的特点 #
- 生命周期感知
- 自动清理观察者
- 数据一致性
- 内存安全
1.2 LiveData的优势 #
- 不会内存泄漏
- 不会因Activity停止而崩溃
- 数据始终保持最新
- 正确处理配置更改
二、基本使用 #
2.1 创建LiveData #
kotlin
class MainViewModel : ViewModel() {
// MutableLiveData用于修改数据
private val _name = MutableLiveData<String>()
// LiveData用于暴露给外部观察
val name: LiveData<String> = _name
fun updateName(newName: String) {
_name.value = newName
}
}
2.2 观察LiveData #
kotlin
class MainActivity : AppCompatActivity() {
private val viewModel: MainViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 观察LiveData
viewModel.name.observe(this) { name ->
binding.tvName.text = name
}
}
}
2.3 在Fragment中观察 #
kotlin
class MainFragment : Fragment() {
private val viewModel: MainViewModel by viewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
// 使用viewLifecycleOwner
viewModel.name.observe(viewLifecycleOwner) { name ->
binding.tvName.text = name
}
}
}
三、LiveData类型 #
3.1 MutableLiveData #
可变的LiveData,可以修改数据。
kotlin
val liveData = MutableLiveData<String>()
// 主线程设置值
liveData.value = "Hello"
// 子线程设置值
liveData.postValue("Hello")
3.2 MediatorLiveData #
可以合并多个LiveData源。
kotlin
val liveData1 = MutableLiveData<String>()
val liveData2 = MutableLiveData<String>()
val mediatorLiveData = MediatorLiveData<String>()
mediatorLiveData.addSource(liveData1) { value ->
mediatorLiveData.value = value
}
mediatorLiveData.addSource(liveData2) { value ->
mediatorLiveData.value = value
}
3.3 自定义LiveData #
kotlin
class LocationLiveData(private val context: Context) : LiveData<Location>() {
private val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
private val locationListener = LocationListener { location ->
value = location
}
override fun onActive() {
// 有活跃观察者时开始监听
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
0L,
0f,
locationListener
)
}
override fun onInactive() {
// 没有活跃观察者时停止监听
locationManager.removeUpdates(locationListener)
}
}
四、数据转换 #
4.1 Transformations.map #
kotlin
val originalLiveData = MutableLiveData<String>()
val upperCaseLiveData = Transformations.map(originalLiveData) { name ->
name.uppercase()
}
originalLiveData.value = "hello"
// upperCaseLiveData的值变为"HELLO"
4.2 Transformations.switchMap #
kotlin
class UserViewModel : ViewModel() {
private val _userId = MutableLiveData<String>()
val user: LiveData<User> = Transformations.switchMap(_userId) { id ->
repository.getUserById(id)
}
fun setUserId(id: String) {
_userId.value = id
}
}
4.3 自定义转换 #
kotlin
fun <X, Y> LiveData<X>.map(transform: (X) -> Y): LiveData<Y> {
val result = MediatorLiveData<Y>()
result.addSource(this) { x ->
result.value = transform(x)
}
return result
}
// 使用
val transformedLiveData = originalLiveData.map { it.uppercase() }
五、合并多个LiveData #
5.1 使用MediatorLiveData #
kotlin
class FormViewModel : ViewModel() {
private val _name = MutableLiveData<String>()
private val _email = MutableLiveData<String>()
val isFormValid = MediatorLiveData<Boolean>()
init {
isFormValid.addSource(_name) {
isFormValid.value = validateForm()
}
isFormValid.addSource(_email) {
isFormValid.value = validateForm()
}
}
private fun validateForm(): Boolean {
val name = _name.value ?: ""
val email = _email.value ?: ""
return name.isNotBlank() && email.contains("@")
}
}
5.2 使用combine扩展函数 #
kotlin
fun <A, B> LiveData<A>.combineWith(
liveData: LiveData<B>
): LiveData<Pair<A, B>> {
val result = MediatorLiveData<Pair<A, B>>()
var valueA: A? = null
var valueB: B? = null
result.addSource(this) {
valueA = it
if (valueA != null && valueB != null) {
result.value = Pair(valueA!!, valueB!!)
}
}
result.addSource(liveData) {
valueB = it
if (valueA != null && valueB != null) {
result.value = Pair(valueA!!, valueB!!)
}
}
return result
}
// 使用
val combinedLiveData = nameLiveData.combineWith(emailLiveData)
六、LiveData与协程 #
6.1 liveData构建器 #
kotlin
val user: LiveData<User> = liveData {
// 协程上下文
val data = repository.getUser()
emit(data)
}
// 带参数
fun getUser(userId: String): LiveData<User> = liveData {
val data = repository.getUser(userId)
emit(data)
}
6.2 emitSource #
kotlin
val user: LiveData<User> = liveData {
// 先发射缓存数据
val cached = database.getUser()
emitSource(cached)
// 然后从网络获取最新数据
val network = api.getUser()
database.save(network)
// 发射最新数据
emit(network)
}
6.3 使用Flow转换为LiveData #
kotlin
val users: LiveData<List<User>> = repository.getUsers()
.asLiveData()
// 带超时配置
val users: LiveData<List<User>> = repository.getUsers()
.asLiveData(timeoutInMs = 5000)
七、观察者模式 #
7.1 Observer接口 #
kotlin
val observer = object : Observer<String> {
override fun onChanged(value: String) {
// 处理数据变化
}
}
liveData.observe(this, observer)
// 移除观察者
liveData.removeObserver(observer)
7.2 observeForever #
kotlin
// 始终观察,需要手动移除
val observer = Observer<String> { value ->
// 处理数据
}
liveData.observeForever(observer)
// 必须手动移除
liveData.removeObserver(observer)
八、最佳实践 #
8.1 使用封装模式 #
kotlin
class MainViewModel : ViewModel() {
// 私有可变LiveData
private val _users = MutableLiveData<List<User>>()
// 公开不可变LiveData
val users: LiveData<List<User>> = _users
fun loadUsers() {
viewModelScope.launch {
_users.value = repository.getUsers()
}
}
}
8.2 使用viewLifecycleOwner #
kotlin
class MainFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
// 正确:使用viewLifecycleOwner
viewModel.data.observe(viewLifecycleOwner) { data ->
// 更新UI
}
// 错误:使用this(Fragment的生命周期)
// viewModel.data.observe(this) { }
}
}
8.3 初始值处理 #
kotlin
class MainViewModel : ViewModel() {
private val _data = MutableLiveData<String>()
val data: LiveData<String> = _data
init {
// 设置初始值
_data.value = ""
}
}
// 或使用空安全处理
viewModel.data.observe(this) { data ->
if (data.isNotEmpty()) {
// 处理数据
}
}
8.4 使用StateFlow替代LiveData #
kotlin
class MainViewModel : ViewModel() {
private val _uiState = MutableStateFlow<UiState>(UiState.Loading)
val uiState: StateFlow<UiState> = _uiState.asStateFlow()
fun loadData() {
viewModelScope.launch {
_uiState.value = UiState.Loading
try {
val data = repository.getData()
_uiState.value = UiState.Success(data)
} catch (e: Exception) {
_uiState.value = UiState.Error(e.message ?: "Unknown error")
}
}
}
}
// 在Activity中观察
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.uiState.collect { state ->
when (state) {
is UiState.Loading -> showLoading()
is UiState.Success -> showData(state.data)
is UiState.Error -> showError(state.message)
}
}
}
}
九、总结 #
本章详细介绍了LiveData:
- LiveData的基本概念和特点
- LiveData的创建和观察
- LiveData的类型
- 数据转换
- 合并多个LiveData
- LiveData与协程
- 观察者模式
- 最佳实践
LiveData是Android架构组件的重要组成部分,合理使用可以简化UI数据更新逻辑。
最后更新:2026-03-26