LiveData实践
LiveData的优点(摘自https://blog.csdn.net/m0_37778101/article/details/103789862)
UI和实时数据保持一致,因为LiveData采用的是观察者模式,这样一来就可以在数据发生改变时获得通知,更新UI。
避免内存泄漏,观察者被绑定到组件的生命周期上,当被绑定的组件销毁(destroy)时,观察者会立刻自动清理自身的数据。
不会再产生由于Activity处于stop状态而引起的崩溃,例如:当Activity处于后台状态时,是不会收到LiveData的任何事件的。
RxLifeCycle: 可以在一定的时机如onstop,ondestroy取消订阅,但是在onstart,OnResume不会恢复,而liveData可以做到
不需要再解决生命周期带来的问题,LiveData可以感知被绑定的组件的生命周期,只有在活跃状态才会通知数据变化。
实时数据刷新,当组件处于活跃状态或者从不活跃状态到活跃状态时总是能收到最新的数据。
解决Configuration Change问题,在屏幕发生旋转或者被回收再次启动,立刻就能收到最新的数据。
关于LiveData的文章,网络上还有很多,对LiveData剖析的极为详尽。科普不是本文要做的事情,自认为也不会比前辈做的更好。本文,仅是自己实践过程中,对认为具有困惑的几点,
做个小小的总结。
1、LiveData的postValue和setValue接口的区别和联系。
查看LiveData的postValue调用如下:
protected void postValue(T value) {boolean postTask;synchronized (mDataLock) {postTask = mPendingData == NOT_SET;mPendingData = value;}if (!postTask) {return;}ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);}private final Runnable mPostValueRunnable = new Runnable() {@Overridepublic void run() {Object newValue;synchronized (mDataLock) {newValue = mPendingData;mPendingData = NOT_SET;}//noinspection uncheckedsetValue((T) newValue);}};
发现postValue接口最终会切换主线程,调用setValue接口。因此我认为postValue和setValue本质上要做的事情是差不多的,区别在于setValue只能在主线程中调用。而postValue可以在子线程中调用。
2、LiveData有粘性事件吗?(粘性事件是可以被事件发出之后才注册的订阅者接收到,也可以在事件发出之后通过主动查询获取事件内容)
有
3、如何消除LiveData的粘性事件?(一种思路)
注册观察者事件时,通过hook技术,改变系统的一些参数。
/*** hook方法 hook系统源码 改变系统的一些参数* @param observer*/// private SafeIterableMap<Observer<T>, ObserverWrapper> mObservers =// new SafeIterableMap<>();private void hook(Observer<T> observer) throws Exception {//获取到LiveData的类对象Class<LiveData> liveDataClass = LiveData.class;// 获取到mObservers的反射对象Field mObserversField = liveDataClass.getDeclaredField("mObservers");// 让mObserversField可以被访问mObserversField.setAccessible(true);// 获取到这个mObserversField的值Object mObservers = mObserversField.get(this);// 获取到mObservers的get方法的反射对象Method get = mObservers.getClass().getDeclaredMethod("get", Object.class);// 设置这个反射对象可以被访问get.setAccessible(true);// 执行这个方法 得到EntryObject invokeEntry = get.invoke(mObservers, observer);// 定义一个空的对象 LifecycleBoundObserverObject observerWrapper = null;if(invokeEntry!=null && invokeEntry instanceof Map.Entry){Object key = ((Map.Entry)invokeEntry).getKey();observerWrapper = ((Map.Entry)invokeEntry).getValue();}if(observerWrapper == null){throw new NullPointerException("ObserverWrapper不能为空");}// 获取到ObserverWrapper的类对象Class<?> superclass = observerWrapper.getClass().getSuperclass();// 获取搭配这个类中的mLastVersion成员变量Field mLastVersionField = superclass.getDeclaredField("mLastVersion");mLastVersionField.setAccessible(true);// 获取到mVersion的反射对象Field mVersionField = liveDataClass.getDeclaredField("mVersion");// 打开权限mVersionField.setAccessible(true);// 得到的就是mVersion在当前类中的值Object o = mVersionField.get(this);// 把它的值给mLastVersionmLastVersionField.set(observerWrapper,o);}
4、注册的观察者,什么时候会被遍历?
(1) postValue、setValue被调用的时候。
(2) 生命周期发生改变的时候。
5、当注册的观察者被遍历时,满足哪些条件,会调用回调接口onChange?
private void considerNotify(ObserverWrapper observer) {if (!observer.mActive) {return;}// Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.//// we still first check observer.active to keep it as the entrance for events. So even if// the observer moved to an active state, if we've not received that event, we better not// notify for a more predictable notification order.if (!observer.shouldBeActive()) {observer.activeStateChanged(false);return;}if (observer.mLastVersion >= mVersion) {return;}observer.mLastVersion = mVersion;//noinspection uncheckedobserver.mObserver.onChanged((T) mData);}
(1) observer.mActive的值为true
(2) observer.shouldBeActive()的值为true
(3) observer.mLastVersion >= mVersion
更多查看源码,这里就不一一展开了。
6、Android架构组件liveData的最低要求
见https://blog.csdn.net/n_fly/article/details/112462662
LiveData实践相关推荐
- LiveData + ViewModel + Room (Google 官文)+Demo
原文地址:lovestack.github.io/2017/11/13/- demo:github.com/lovestack/V- 本指南适用于那些过去构建应用程序有基础知识,现在想知道构建强大的生 ...
- Android Jetpack组件之 LiveData使用-源码
1.前言 最近简单看了下google推出的框架Jetpack,感觉此框架的内容可以对平时的开发有很大的帮助,也可以解决很多开发中的问题,对代码的逻辑和UI界面实现深层解耦,打造数据驱动型UI界面. A ...
- 【译】LiveData 在 SnackBar/Navigation 情景下的使用(SingleLiveEvent)
前言 本文翻译自[LiveData with SnackBar, Navigation and other events (the SingleLiveEvent case)],详细介绍了 liveD ...
- Android的MVVM架构的单Activity应用实践
前言 谈Android架构大家很容易想到MVC.MVP和MVVM. 1.MVC 首先分析一下上面各层之前对应的Android代码,layout.xml里面的xml文件就对应于MVC的view层,里面都 ...
- Jetpack MVVM 七宗罪之四: 使用 LiveData/StateFlow 发送 Events
久违的 " Jetpack MVVM 七宗罪 " 系列,今日再开.本系列主要盘点 MVVM 架构中各种常见错误写法,并针对性的给出最佳实践,帮助大家掌握 Jetpack 组件最正确 ...
- 有小伙伴说看不懂 LiveData、Flow、Channel,跟我走
背景 Kotlin Flow 是基于 Kotlin 协程基础能力搭建的一套数据流框架,从功能复杂性上看是介于 LiveData 和 RxJava 之间的解决方案.Kotlin Flow 拥有比 Liv ...
- Google 宣布废弃 LiveData.observe 方法
本篇文章作为技术动态了解即可,废弃 LiveData.observe() 扩展方法,已经不是什么新的新闻了,在很久以前,Google 废弃掉这个方法的时候,第一时间我在 朋友圈 和 掘金沸点 发过一个 ...
- 直播聊天室的无限用户优化实践(六千字技术文)
融云近期推出直播 SDK,两步即可实现视频直播能力.在第二步"开始直播"阶段,调用一个接口就能发布视频流,其他用户便可加入房间观看直播并在公屏发送弹幕与主播互动.移步[融云全球互联 ...
- Android实战——单元测试从吹水到实践
目录 1.单元测试到底需要不需要了? 开发时间紧张,不需要做单元测试了吧? 开发经验丰富,不需要做单元测试了吧? 或许存在一种"自动化"的测试,就不需要做单元测试了吧? 2.单元测 ...
最新文章
- JDK 13中的JEP 355文本块
- 开机没有自检声,显示器无信号及各版本BIOS报警信号大全 转
- nodepad++通过正则表达式,删除带有特殊字符的某一行
- 【持续更新】微电子专业术语常用缩写英汉对照
- python计算机视觉pdf百度云下载_Python计算机视觉编程(pdf+epub+mobi+txt+azw3)
- 【obs owt】屏幕采集创建DXGI
- 【51单片机】基于51单片机的时钟电子锁设计
- python jinja2_Python Jinja2使用方法
- java实现上传寸照并剪裁,给寸照换背景_用java处置图片(jpg,png,gif.)的背景颜色
- Chartboost ane sdk 使用教程
- 设置Cookie的生命周期
- 利用机器学习预测外汇汇率
- 大话赛宁云 | 训系列-如何构建网络空间的“练兵场”
- 拍沪牌服务器响应,上海虹口代拍沪牌费用,百兆光线实时响应
- 浙江理工大学c语言作业网站,浙江理工大学 我的编程之路 零基础学C/C++ 200题 标程/题解...
- OpenGL ES 实现瘦脸大眼效果
- 【Superset】Jinja模板功能及设置动态参数
- Xcode自带的instrument中的Automation实现自动化测试简单使用
- 安装burp2022 --illegal-access=permit
- SaltStack常用模块——file