当前位置: 首页 > news >正文

Livedata:感知生命周期变化,如何更新数据?避免内存泄漏,黏性事件

目录

Livedata定义

Livedata的Obsever方法

Livedata更新数据的两种方式

setValue

1,同步数据

2,分发数据

3,通知观察者

livedata如何避免内存泄漏

 livedata中的黏性事件


Livedata定义

        Livedata的定义:具有生命感知可观察数据持有者,可以感知持有者的生命周期状态,只在持有者活跃时才更新数据

        Livedata的使用非常简单,创建一个Livedata对象,然后调用Observer方法,传入要观察的生命周期对象和自定义的观察者

    val data1 : LiveData<String> = MutableLiveData("hello world")fun test(){data1.observe(this, object : Observer<String>{override fun onChanged(value: String) {}})}

先来看一下他的Observer方法:

Livedata的Obsever方法

       @MainThreadpublic void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {//检测非主线程报错assertMainThread("observe");//检测owner生命周期if (owner.getLifecycle().getCurrentState() == DESTROYED) {// ignorereturn;}//将生命周期owner和自定义观察者observer包装起来,从而可以监听其生命周期变化LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);//包装好的对象,以我们自定义的的观察者为key,存入一个集合ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);//报错检测机制if (existing != null && !existing.isAttachedTo(owner)) {throw new IllegalArgumentException("Cannot add the same observer"+ " with different lifecycles");}if (existing != null) {return;}//包装后的对象给到LifecycleRegistryowner.getLifecycle().addObserver(wrapper);}

Livedata中有两个关键元素:当前Livedata的版本号mVersion,和当前的观察者集合mObservers

public abstract class LiveData<T> {//每一个LiveData对象有一个mVersion属性,记住这个属性很关键。
private int mVersion;//一个支持迭代时更新数据的Iterable
private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =new SafeIterableMap<>();
}

Livedata更新数据的两种方式

setValue

setValue可以分为三步走:

1,同步数据

@MainThread
protected void setValue(T value) {//主线程检查,非主线程报错assertMainThread("setValue");//版本号+1mVersion++;//更新数据mData = value;//分发数据dispatchingValue(null);
}

2,分发数据

void dispatchingValue(@Nullable ObserverWrapper initiator) {、、省略其他代码
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {//遍历我们定义的观察者的集合considerNotify(iterator.next().getValue());if (mDispatchInvalidated) {break;}
}、、省略其他代码
}

3,通知观察者

        considerNotify中对observer的状态进行过滤,以及版本进行判断,全部通过后,使用mObserverde的onChanged进行数据回调。

private void considerNotify(ObserverWrapper observer) {if (!observer.mActive) {return;}//生命周期owner至少是STARTEDif (!observer.shouldBeActive()) {observer.activeStateChanged(false);return;}if (observer.mLastVersion >= mVersion) {return;}observer.mLastVersion = mVersion;//这里是我们实现的数据改变后回调方法observer.mObserver.onChanged((T) mData);
}@Override
boolean shouldBeActive() {return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}

livedata如何避免内存泄漏

LiveData 通过与其观察者的 (如 Activity/Fragment)生命周期绑定来实现免内存泄漏。

  1. 当通过 observe(LifecycleOwner, Observer) 方法注册观察者时,LiveData 会将 Observer 和 LifecycleOwner 包装成一个 LifecycleBoundObserver 对象
  2. 这个包装对象实现了LifecycleEventObserver接口,从而能够监听生命周期变化
  3. 当关联的lifecycle对象生命周期变为Destory时,Livedata会自动地将这个观察者从列表中移除,这样就确保了观察者不会因为被 LiveData 持有而阻止了 LifecycleOwner 的被回收,从而避免了内存泄漏。

 livedata中的黏性事件

“黏性事件”是指:当一个新的观察者开始观察 LiveData 时,如果该 LiveData 之前已经设置过值,那么这位新观察者会立即收到最后一次设置的数据(即最新数据)。

当生命周期对象的生命周期变化时,会走一遍事件分发,数据回调流程

这个特性的实现原理主要依赖于一个版本号(mVersion)机制:

  1. 每次通过 setValue() 或 postValue() 更新数据时,mVersion 都会递增。
  2. 每个观察者包装类 (ObserverWrapper) 内部都记录着自己最后一次接收到的数据的版本号 (mLastVersion)。
  3. 当观察者的生命周期变为活跃状态时,LiveData 会检查其 `mLastVersion` 是否小于 LiveData 当前的 mVersion。如果是,就认为这个观察者的数据是“过时的”,便会立即向其分发最新的数据

参考:

LiveData原理面试一问还不懂?

由浅入深,详解 LiveData 的那些事

http://www.dtcms.com/a/349221.html

相关文章:

  • TCP--执行Linux命令(虚拟xshell)
  • 苍穹外卖项目实战(日记十)-记录实战教程及问题的解决方法-(day3-2)新增菜品功能完整版
  • 不再让Windows更新!Edge游戏助手卸载及关闭自动更新
  • Leetcode 3661. Maximum Walls Destroyed by Robots
  • 阿里AI模型获FDA突破性医疗器械认定,AI医疗走向国际舞台,来近屿智能系统学习AIGC大模型技术
  • 芋道前端项目部署后刷新 404 的解决办法(Nginx 配置教程)
  • 计算机网络:聊天室(UDP)
  • 器件(十)——经典封装类型总结
  • JUC之ThreadLocal
  • MySQL的安装和卸载指南(入门到入土)
  • python写上位机并打包250824
  • 第04章 SPSS简介与数据库构建
  • 2025最新ncm转MP3,网易云ncm转mp3格式,ncm转mp3工具!
  • C6.1:发射极偏置放大器
  • 支持多种模型,无限AI生图工具来了
  • 智元精灵GO1 agibot数据转换Lerobot通用格式数据脚本
  • 3.2 半导体随机存取存储器 (答案见原书 P168)
  • 你在四阶段数据成熟度旅程中处于哪个阶段?
  • 高数 不定积分(4-3):分部积分法
  • APP逆向——某站device-id参数(2)
  • 56 C++ 现代C++编程艺术5-万能引用
  • Linux内核ELF文件签名验证机制的设计与实现(C/C++代码实现)
  • DeepSeek对采用nginx实现透传以解决OpenShift 4.x 私有数据中心和公有云混合部署一套集群的解答
  • 机床智能健康管理系统:工业母机数字化转型的核心引擎​
  • 在mysql中,modify ,change ,rename to的作用是什么
  • AI使用日志(一)--Cursor和Claude code初体验
  • 用 Python 探索二分查找算法:从基本原理到实战最佳实践
  • 自回归(Auto-Regressive, AR),自回归图像生成过程
  • 【Canvas与旗帜】蓝圈汤加旗
  • 基于蓝牙的stm32智能火灾烟雾报警系统设计