概述
- LiveData 是一个持有数据的类,它持有的数据是可以被观察者订阅的,当数据被修改时就会通知观察者。观察者可以是 Activity、Fragment、Service 等。
- LiveData 能够感知观察者的生命周期,只有当观察者处于激活状态(STARTED、RESUMED)才会接收到数据更新的通知,在未激活时会自动解注册观察者,以减少内存泄漏。
- 使用 LiveData 保存数据时,由于数据和组件是分离的,当组件重建时可以保证数据不会丢失。
优点
- 确保 UI 界面始终和数据状态保持一致。
- 没有内存泄漏,观察者绑定到 Lifecycle 对象并在其相关生命周期 destroyed 后自行解除绑定。
- 不会因为 Activity 停止了而奔溃,如 Activity finish 了,它就不会收到任何 LiveData 事件了。
- UI 组件只需观察相关数据,不需要停止或恢复观察,LiveData 会自动管理这些操作,因为 LiveData 可以感知生命周期状态的更改。
- 在生命周期从非激活状态变为激活状态,始终保持最新数据,如后台 Activity 在返回到前台后可以立即收到最新数据。
- 当配置发生更改(如屏幕旋转)而重建 Activity / Fragment,它会立即收到最新的可用数据。
- LiveData 很适合用于组件(Activity / Fragment)之间的通信。
使用
LiveData 有两种使用方式,结合 ViewModel 使用以及直接继承 LiveData 类。
结合 ViewModel 使用
以下代码场景:点击按钮提示一个名字。
1 | class MyViewModel : ViewModel() { |
1 | class LiveDataActivity : AppCompatActivity() { |
让数据(name)和组件(LiveDataActivity)分离,当 Activity 重建时,数据(name)不会丢失。
直接继承 LiveData 类
以下代码场景:在 Activity 中监听 Wifi 信号强度。
1 | class WifiLiveData private constructor(context: Context) : LiveData<Int>() { |
1 | class LiveDataActivity : AppCompatActivity() { |
当组件(Activity)处于激活状态(onActive)时注册广播,处于非激活状态(onInactive)时注销广播。
源码解析
observe 注册流程
LiveData 通过 observe() 方法将被观察者 LifecycleOwner (Activity / Fragment) 和观察者 Observer 关联起来。
1 | LiveData.observe(LifecycleOwner owner , Observer<T> observer) |
进入 LiveData 的 observe() 方法中
1 | public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) { |
从上面的代码可知,observe() 方法最终是会调用:
1 | LifecycleOwner.getLifecycle().addObserver(LifecycleObserver) |
因此 LiveData 是能够感知观察者的生命周期变化的。
感知生命周期变化
通过以上的分析,我们知道 LifecycleBoundObserver(LiveData 的内部类)是观察者,以下具体分析 LifecycleBoundObserver 的实现过程。
1 | class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver { |
当组件(Activity / Fragment)的生命周期发生改变时,onStateChanged() 方法将会被调用。若当前处于 DESTROYED 状态,则会移除观察者;若当前处于激活状态,则会调用 activeStateChanged() 方法。activeStateChanged() 方法位于父类 ObserverWrapper 中。
1 | void activeStateChanged(boolean newActive) { |
再看看最终调用的 dispatchingValue() 方法。
1 | private void dispatchingValue(@Nullable ObserverWrapper initiator) { |
可以看到 dispatchingValue() 方法里面再通过 considerNotify() 方法将消息通知下去。
1 | private void considerNotify(ObserverWrapper observer) { |
上面的 mObserver 正是我们调用 observe() 方法时传入的观察者。
总结上面的分析就是:调用 LiveData.observe(LifecycleOwner owner , Observer
通知观察者更新数据的方式
LiveData 为我们提供了两种改变数据后,通知观察者更新数据的方式,一个是 setValue() 方法(必须在主线程调用),另一个是 postValue() 方法(必须在子线程调用)。
setValue() 方法
1 |
|
dispatchingValue() 方法会跑我们上面分析的流程,最终把改变的数据 value(对应上面的 mData)作为 onChanged() 方法的参数传给观察者。
postValue() 方法
1 | protected void postValue(T value) { |
可以看出 postValue() 方法最终也会在主线程中调用 setValue() 方法。
参考资料: