[关闭]
@universal 2023-02-08T02:22:14.000000Z 字数 1452 阅读 113

LiveData相关

未分类


LiveData相关

LiveData 如何感知生命周期的变化

observer的时候会传入LifecycleOwner,liveData的observer方法中会将owner和observer包装成wrapper(LifecycleEventObserver),最后owner.getlifecycle().addObserver()实现感知生命周期的变化的能力。

LiveData 是如何避免内存泄漏的

虽然observer是匿名内部类,但是liveData具有感知生命周期的能力,会在DESTORY状态时自动移除观察者,从而避免内存泄漏。

LiveData 是粘性的吗?若是,它是怎么做到的?

是。
LiveData中有一个mData存储值,一个mVersion记录版本,每一次的setValue()都会更新这两个值,通知观察者时,observer里会有一个mLastVersion记录上一次被通知时版本,如果mLastVersion >= mVersion,那么观察者不会调用 onChanged() 方法。但是如果是新创建的观察者,它的mLastVersion是初始值,这时候新观察者在添加时就会触发一次老值的分发(也就是LiveData的粘性,新观察者被老值通知到了)。

另外:
LiveData通知的场景:
1. 值变化,通知所有观察者
2. 新增观察者,或者已添加的某个观察者生命周期发生变化(如变化为START),会通知单个观察者

LiveData分发的条件:
1. 观察者是否活跃(mActive)
2. 观察者的生命周期是否活跃
3. 观察者的版本号是否最新

粘性的 LiveData 会造成什么问题?怎么解决?

会造成一些页面的切换时,切换回上一层页面,上层页面又执行一次旧数据的逻辑。
解决方案:
1. Value中添加一个是否被消费过的bool值,如果没被消费过,再处理具体业务逻辑
2. 反射修改 mLastVersion为最新版本号,但是这样的做法会破坏粘性,只适用于特定场景
3. 官方的解决方案:SingleLiveEvent(继承自MutableLiveData), SingleLiveEvent中定义一个值表示是否被消费过,在observe()方法中包一层observe{},在它onChange时判断一下这个值,如果没有被消费过,再调用真正的观察者的onChange通知数据更新
4. Kotlin Flow也可以解决(不会,面试的时候能不说就不说吧。。)

什么情况下 LiveData 会丢失数据

postValue()会丢失数据
postValue会先把值暂存mPendingData变量,等到runnable真正执行的时候才会将mPendingData赋值给mData,如果在runnable执行之前再调用postValue,mPendingData被覆盖,就会造成数据丢失。
解决:如果在主线程就直接使用setValue,如果不在,手动延一下postVaule的频率。

在 Fragment 中使用 LiveData 需注意些什么

绑定viewLifecycleOwner而不是fragment本身,如果是fragment之间的切换,不会调用到DESTORY阶段,就会导致观察者被通知执行响应逻辑,但是view会因为fragment的onDestroyView变为DESTORY阶段。

LiveData 变换数据异步化

CoroutineLiveData,将更新 LiveData值的操作封装到一个挂起方法中, 可以通过协程上下文指定执行的线程。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注