1. LiveData是什么
LiveData 是一种可观察的数据存储器类。与常规的可观察类不同,LiveData 具有生命周期感知能力,即它遵循其他应用组件(如 Activity/Fragment)的生命周期。这种感知能力可确保 LiveData仅更新处于活跃生命周期状态的应用组件观察者。
2. LiveData特点
实时数据刷新:当组件处于活跃状态或者从不活跃状态到活跃状态时总是能收到最新的数据;
不会发生内存泄漏:observer会在LifecycleOwner状态变为DESTROYED后自动remove;
不会因 Activity 处于STOP等状态而导致崩溃:如果LifecycleOwner生命周期处于非活跃状态,则它不会接收任何 LiveData事件;
不需要手动解除观察:开发者不需要在onPause或onDestroy方法中解除对LiveData的观察,因为LiveData能感知生命周期状态变化,所以会自动管理所有这些操作;
数据始终保持最新状态:数据更新时,若LifecycleOwner为非活跃状态,那么会在变为活跃时接收最新数据。例如,曾经在后台的 Activity 会在返回前台后,observer立即接收最新的数据等;
LiveData如何实现订阅者模式,如何处理发送事件?
自身通过注册观察者,在数据更新时进行数据变更的通知;
如何做到感知生命周期的,怎么跟 LifecycleOwner 进行绑定的?
将Observer与LifeCycleOwner组合成新的观察者包装类,进而实现绑定以及生命周期感知;
LiveData 只在 LifecycleOwner的active状态发送通知,是怎么处理的?
非活跃状态数据无法感知生命周期变化,同时在considerNotify时,如果包装后的观察者不是活跃状态也无法发送通知;
LiveData 会自动在 DESTROY 的状态下取消订阅,是怎么处理的?
感应到生命周期为DESTROYED时会调用removeObserver()方法取消订阅;
生命周期变化后数据处理流程是怎么样的?
onStateChanged ——> activeStateChanged ——> dispatchingValue ——> considerNotify ——> onChanged
为什么观察者只能与一个LifecycleOwner绑定,而不是多个?
绑定多个的话,LiveData的生命周期感知能力就乱掉了,会有很多问题;
LiveData的粘性事件?
之前的Observer已经订阅并更新数据,mVersion与mLastVersion不再保持同步那么再新增一个Observer,他也会立即受到旧的消息通知
(mLastVersion < mVersion,不会走进return的逻辑);
3.实现livedata的主要几个方面?
LiveData 遵循观察者模式。 当底层数据发生变化时,LiveData 会通知 Observer 对象。 您可以整合代码以在这些 Observer 对象中更新界面。 这样一来,您无需在每次应用数据发生变化时更新界面,因为观察者会替您完成更新。
LiveData的生命周期感知。LiveData是一个生命周期感知的组件,它可以感知宿主组件(如Activity、Fragment)的生命周期状态变化。LiveData 会自动管理观察者的生命周期,并在宿主组件处于活跃状态时通知观察者,而在非活跃状态下停止通知。
LiveData线程安全。LiveData 保证数据的更新和通知操作是在主线程进行的,以确保数据更新的安全性和一致性当数据发生变化时,LiveData 会在主线程中通知观察者,从而避免了多线程操作数据的问题
LiveData的背压支持。LiveData提供了背压支持,可以处理观察者无法及时处理所有数据变化的情况,当观察者无法及时处理数据变化时,LiveData会根据背压策略进行处理,如丢弃新数据,缓存数据等。
LiveData的数据粘性。LiveData 支持数据粘性,即当观察者订阅LiveData 时,会立即收到近的数据,而不仅仅是后续的数据变化。这对于初始化数据或恢复状态很有用,确保观察者能够立即获取到新的数据
4.关于liveData的各种方法
public T getValue()
: 获取 LiveData 里的数据public boolean hasActiveObservers()
: 是否存在活跃的观察者对象public boolean hasObservers()
:是否有观察者对象public void observe(LifecycleOwner owner, Observer observer)
:添加感知生命周期的观察者对象public void observeForever(Observer observer)
:添加无生命周期感知的观察者对象public void removeObserver(final Observer observer)
:移除对应的观察者对象public void removeObservers(final LifecycleOwner owner)
:根据生命周期对象移除观察者对象protected void setValue(T value)
:设置 LiveData 容器的数据protected void postValue(T value)
: 在主线程设置 LiveData 容器的数据protected void onActive()
:当活跃的观察者对象数量大于 0 时调用,即有活跃的观察者对象时调用protected void onInactive()
:当活跃的观察者对象数量等于 0 时调用,即无活跃的观察者对象时调用liveData经常运用在?
ViewModel的主要作用是存放页面所需要的各种数据,而当这些数据发生变化时,我们采用接口的方式实现对页面的通知。 这样做是可行的,但如果要观察的数据很多,则需要定义大量的接口,代码显得冗余。 为此,Android为我们提供了 LiveData 组件,帮助我们完成ViewModel与页面组件之间的通信。 所以, LiveData通常是被放在MVVM框架中的ViewModel中使用 。
什么是数据倒灌?
一句话总结就是:先给LiveData设置了value,然后监听者才开始对LiveData进行监听,这时LiveData的value会立马回调给监听者。
虽然从google设计者的角度来看,这并不是一个设计缺陷,但从我们使用者角度来看,其实很多场景下这并不是我们想要的。
我们更期望的是:只收到对LiveData开始监听之后的value,开始监听之前的旧value不要回调给我。
现有解决方案及各自缺陷
1.Event 事件包装器
对于多观察者的情况,只允许第一个观察者消费,这不符合现实需求;
而且手写 Event 事件包装器,在 Java 中存在 null 安全的一致性问题。
2.反射干预 Version 的方式
存在延迟,无法用于对实时性有要求的场景;
并且数据会随着 SharedViewModel 长久滞留在内存中得不到释放。
3.官方最新 demo 中的 SingleLiveEvent
是对 Event 事件包装器 一致性问题的改进,但未解决多观察者消费的问题;
而且额外引入了消息未能从内存中释放的问题。
4.UnPeekLiveData
提出【数据倒灌】名词大佬写的一个库UnPeekLiveData
缺点:改动大,逻辑复杂,小专栏收费
1.livedata采用观察者模式,内部通过监听生命周期、版本号方式维护数据,保证能及时、有效的刷新。
2.Livedata可以配个viewModel,实现MVVM架构。
3.call Active方法的条件:上次没有处于活跃的观察者(带有lifecycleOwner),并且当前有处于活跃的观察者。
4.call Inactive方法的条件:上次有处于活跃的观察者(带有lifecycleOwner),并且当前没有处于活跃的观察者。
5.LiveData内部通过监听组件周期,自动注销观察者,防止内存泄漏。
6.在跨线程更新数据时,通过volatile和加锁方式来保证数据的一致性。
7.内部使用SafeIterableMap 来维护Observer,可以在迭代Observer的同时将其移除掉。
一个Observer对应一个lifecycleOwner,否则将报错。