前言
LiveData 的设计初衷,强调其生命周期感知、简化UI组件的数据更新和内存管理,适用于ViewModel数据共享的场景。
下面首先我会先介绍LiveData是什么,然后再介绍源码部分。 想看源码的可以直接跳到源码解析部分
一、LiveData 简介
1. 什么是 LiveData?
LiveData 是一个具有生命周期感知的数据持有类,可帮助 Android UI 组件在数据变化时自动更新。说明它是如何依赖 Android 架构组件库中的 ViewModel 和 Lifecycle,实现数据共享和观察者管理。
2. LiveData 的特点和优势
特点
-
生命周期感知:LiveData 自动根据观察者(如 Activity 或
Fragment)的生命周期进行管理,仅在界面活跃时通知数据更新,避免不必要的 UI 操作和内存泄漏。 -
数据持有类:LiveData 本身是一个数据持有类,能够存储数据。可以在 ViewModel 中创建一个 LiveData 实例来持有数据,使得数据能在配置变更时保持不变。
-
自动更新 UI(与DataBinding 配合使用):当 LiveData 数据发生变化时,它会自动通知注册的观察者更新 UI,减少手动调用 UI 更新逻辑的需求。
-
线程安全:LiveData 内部处理了线程同步,确保在主线程中更新 UI 时不会遇到线程安全问题。
优势 ( 适用场景 )
-
减少内存泄漏:LiveData 能够观察 UI 组件的生命周期,仅在组件活跃状态下更新数据,降低了因生命周期不当导致的内存泄漏风险。
-
简化 UI 控制逻辑:LiveData 自动管理数据状态变化,使得 UI 与数据同步变得轻松,代码逻辑更清晰,易于维护。
-
应对配置变更:与 ViewModel 配合使用,LiveData 能在配置变更时(如旋转屏幕)保存数据状态,避免重新加载和数据丢失的问题。
-
实时数据响应:LiveData 可以直接连接到数据库(例如 Room),实现数据实时响应,数据库更新时自动刷新UI,不需手动监听数据库变化。
-
线程支持:LiveData 提供 postValue 和setValue,可以分别在子线程和主线程中更新数据,帮助在异步任务完成后切换到主线程更新 UI。
二、LiveData 的架构设计
LiveData 的架构设计围绕着生命周期感知、数据订阅发布机制以及数据持有进行设计,旨在简化 UI 层的数据管理,确保数据在不同生命周期阶段的合理更新。
分析源码前 我们先看看LiveData的UML类图:
注:如果不清楚UML关系类图的可以看看下面链接,欢迎大佬们莅临指导
链接: UML类图绘制规则
类图详细说明
-
LifecycleOwner
关系:与 Lifecycle 是关联关系,通过 getLifecycle() 方法获取 Lifecycle 对象。
功能:表示具备生命周期的组件,提供 getLifecycle() 方法以获取其生命周期状态,允许 LiveData 自动管理观察者的活跃状态。 -
Lifecycle
关系:LifecycleOwner 拥有 Lifecycle;Lifecycle 聚合 LifecycleObserver。
功能:管理生命周期事件并通知观察者,通过 addObserver() 和 removeObserver() 方法添加或移除观察者。getCurrentState() 方法提供当前的生命周期状态。 -
LifecycleObserver
关系:LiveData 通过 LifecycleBoundObserver 实现 LifecycleObserver,用来监听 Lifecycle 的状态变化。
功能:用于观察 Lifecycle 的状态,在 LiveData 中自动管理观察者的活跃性。LifecycleObserver 可以跟踪 LifecycleOwner 的生命周期事件,自动激活和暂停观察者。 -
LiveData
关系:与 LifecycleObserver 是组合关系:LiveData 使用内部类 LifecycleBoundObserver 管理 LifecycleOwner 的状态。与 Observer 是依赖关系:LiveData 依赖 Observer,通过 observe() 注册观察者。
功能:提供观察数据的功能,当数据变化时通知观察者。包括 observe() 方法绑定带有 LifecycleOwner 的观察者,observeForever() 方法绑定无生命周期的观察者。 -
LifecycleBoundObserver
关系:LifecycleBoundObserver 是 LiveData 的内部类,继承自 LifecycleObserver。
功能:LifecycleBoundObserver 将 Observer 与特定的 LifecycleOwner 绑定,使得 LiveData 根据 Lifecycle 状态控制观察者的激活或暂停。 -
Observer
关系:与 LiveData 是依赖关系,通过 onChanged() 方法响应数据的变化。
功能:Observer 定义了 onChanged() 方法,当 LiveData 中的数据更新时被调用,用于响应数据的变化。 -
MutableLiveData
关系:继承自 LiveData,是一种可变的 LiveData。
功能:通过 setValue() 和 postValue() 方法,允许外部更新数据。 -
MediatorLiveData
关系:继承自 LiveData,并且组合多个 LiveData 数据源。
功能:通过 addSource() 和 removeSource() 方法,可以动态添加或移除 LiveData 数据源。MediatorLiveData 会监听所有数据源的变化,并在指定条件下触发观察者的更新。
UML类图看完了,那我们看看他们大致的时序图
看不懂图没关系 我们看一下文字描述,图文结合就能懂了
注:在 LiveData 的上下文中,“if in active state” 表示观察者(Observer)处于“活跃状态”时,LiveData 会将数据通知给该观察者。这个活跃状态(active state)是由 LifecycleOwner 的生命周期状态决定的。
活跃状态的定义
跃状态(Active State): 在 LiveData 中,观察者会被标记为活跃,当它的 LifecycleOwner 处于 STARTED 或 RESUMED 状态时(比如 Activity 正在前台运行,或 Fragment 正在显示)。只有当观察者处于活跃状态时,它才会接收到 LiveData 的数据更新。
非活跃状态(Inactive State): 如果 LifecycleOwner 的状态低于 STARTED(如 CREATED 或 DESTROYED),则此时的观察者被视为“非活跃状态”。非活跃状态下,LiveData 不会通知观察者数据更新,以节省资源。
时序图的详细流程:
1. 观察者注册(调用 observe() 方法)
-
Activity/Fragment(或其他 LifecycleOwner)调用 LiveData.observe(),传入
LifecycleOwner 和 Observer。 -
LiveData 检查 LifecycleOwner 的生命周期状态:
1、如果状态为 STARTED 或 RESUMED,则标记 Observer 为活跃状态,并立即触发通知,将当前数据推送给该观察者。
如果状态低于 STARTED,则不会立即通知数据,等待状态更新到活跃时再通知。
2、LiveData 将该 Observer 添加到观察者列表中,监听其生命周期变化。
2. 生命周期状态改变
- 当 LifecycleOwner 的生命周期状态变化(如从 CREATED 到 STARTED),LiveData 会监听到该事件。
- LiveData 再次检查 LifecycleOwner 的状态:
1、如果新的状态为 STARTED 或 RESUMED,LiveData 将此观察者标记为活跃,并触发数据通知(如果有新数据)。
2、如果状态低于 STARTED(例如 DESTROYED),LiveData 将停止对该观察者的更新,可能会从观察者列表中移除该观察者。
3. 数据更新(调用 setValue() 或 postValue())
- 当调用 setValue() 或 postValue() 更新 LiveData 的数据时:
1、 LiveData 将数据标记为“已更新”状态,准备通知所有活跃的观察者。
2、 如果当前没有活跃的观察者,LiveData 将暂存新数据,等待后续观察者变为活跃时再通知。
3、如果有活跃的观察者,则将最新数据立即推送给所有活跃的观察者。
4. 数据通知
1、LiveData 会遍历所有活跃状态的观察者,将最新数据推送给每个观察者。
2、Observer 的 onChanged() 方法被调用,以接收最新的数据并触发 UI 更新。
5. 观察者移除
当 LifecycleOwner 的生命周期状态到达 DESTROYED 状态时,LiveData 自动从观察者列表中移除该观察者。
这一步确保不再对已销毁的 LifecycleOwner 进行数据通知,防止内存泄漏。
三、源码解析
了解了LiveData大致工作原理后 下面我们从源码角度开始分析
1. 基本使用
在实际项目中,LiveData 通常配合 ViewModel 使用。下面是 LiveData 的基本使用步骤:
在 ViewModel 中定义 LiveData,并通过 setValue() 或 postValue() 更新数据。
在 Activity 或 Fragment 中通过 observe() 注册观察者,接收 LiveData 的数据更新。
// MyViewModel.kt
class MyViewModel : ViewModel() {
private val _data = MutableLiveData<String>()
val data: LiveData<String> = _data
fun updateData(newData: String) {
_data.value = newData
}
}
// MyActivity.kt
class MyActivity : AppCompatActivity() {
private lateinit var viewModel: MyViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)