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:

  1. LiveData的基本概念和特点
  2. LiveData的创建和观察
  3. LiveData的类型
  4. 数据转换
  5. 合并多个LiveData
  6. LiveData与协程
  7. 观察者模式
  8. 最佳实践

LiveData是Android架构组件的重要组成部分,合理使用可以简化UI数据更新逻辑。

最后更新:2026-03-26