LiveData是什么?
LiveData 是 Jetpack 中的一个组件。LiveData是一种可观察的数据存储器类,LiveData具有生命周期感知能力,这种感知能力可确保LiveData仅更新处于活跃生命周期状态的应用组件观察者。LiveData一般配合ViewModel使用。
LiveData的使用
class CommonViewModel:ViewModel() {
val commonData: MutableLiveData<String> = MutableLiveData()
fun updateContent(name: String) {
// liveData的第一种发送数据的方法
//commonData.postValue(name)
// liveData的第二种发送数据的方法
//commonData.setValue(name)
}
}
通过在ViewModel中创建MutableLiveData对象,然后调用liveData的postValue()或者setValue()进行数据的发送。
//只在活跃状态下才能收到数据变更
mViewModel.commonData.observe(this) {
// 进行数据的接收
}
//不区分是否活跃都能收到数据变更
mViewModel.commonData.observeForever {
// 进行数据的接收
}
在Activity/Fragment中通过liveData的observe方法进行数据的接收。
对于上面livaData的两种发送数据的方法的区别是:
setValue()只能在主线程调用。
postValue()可以在子线程调用,但是最终还是会调用setValue()进行数据的发送。
LiveData的原理
LiveData的原理非常简单。它使用观察者模式来通知观察者数据发生了变化。当LiveData对象被观察时,它会将观察者添加到观察者列表中。当LiveData对象发生变化时,它会通知观察者。为了避免内存泄漏,LiveData还需要与生命周期组件一起使用,以确保观察者只会在活动的生命周期内接收数据更新。
LiveData通过与Lifecycle组件配合使用,实现了对观察者的自动添加和移除。当Activity或Fragment处于STARTED或RESUMED状态时,LiveData会将观察者添加到观察者列表中,并开始向观察者发送数据更新通知。当Activity或Fragment处于STOPPED或DESTROYED状态时,LiveData会自动将观察者从观察者列表中移除,停止向其发送数据更新通知。这样一来,我们就不必手动管理LiveData的观察者订阅和取消订阅,极大地简化了代码的编写和维护。
LiveData的数据粘性
在 LiveData 中,数据粘性是指当LiveData中的数据发生变化时,即使观察者在数据变化之后才注册,也能立即收到最新的数据变化通知。
public class NoStickyLivaData<T> extends LiveData {
private boolean stickFlag = false;
@Override
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer observer) {
super.observe(owner, observer);
if (!stickFlag) {
hook(observer);
stickFlag = true;
}
}
private void hook(Observer<? super T> observer) {
//1.得到mLastVersion
// 获取到LiveData的类的mObservers对象
// SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers
try {
Class<LiveData> aClass = LiveData.class;
Field mObservers = aClass.getDeclaredField("mObservers");
mObservers.setAccessible(true);
//获取到这个成员变量的对象 new SafeIterableMap<>()
Object mObserversObject = mObservers.get(this);
Class<?> mObserversClass = mObserversObject.getClass();
Method get = mObserversClass.getDeclaredMethod("get", Object.class);
get.setAccessible(true);
//执行get方法 mObservers.get(observer)
Object invokeEntry = get.invoke(mObserversObject,observer);
Object observerWrapper = null;
if (invokeEntry != null && invokeEntry instanceof Map.Entry) {
observerWrapper = ((Map.Entry)invokeEntry).getValue();
}
if (observerWrapper == null) {
throw new NullPointerException("observerWraper is null");
}
Class<?> superclass = observerWrapper.getClass().getSuperclass();
Field mLastVersion = superclass.getDeclaredField("mLastVersion");
mLastVersion.setAccessible(true);
// 2.得到mVersion
Field mVersion = aClass.getDeclaredField("mVersion");
mVersion.setAccessible(true);
//3.把mVersion的数据填入到mLastVersion中
Object mVersionValue = mVersion.get(this);
mLastVersion.set(observerWrapper,mVersionValue);
} catch (Exception e) {
e.printStackTrace();
}
}
}
解决方式是反射更改版本号,使observer.mLastVersion 和 mVersion相同。