首页 > 其他分享 >Android JetPack~LiveData(二) 数据倒灌问题

Android JetPack~LiveData(二) 数据倒灌问题

时间:2023-05-02 21:23:09浏览次数:46  
标签:JetPack mVersion LiveData mLastVersion 倒灌 Android 数据

  1. Android数据绑定技术一,企业级开发
  2. Android数据绑定技术二,企业级开发
  3. Android  JetPack~ DataBinding(数据绑定)(一)    集成与使用
  4. Android  JetPack~ LiveData (一)   介绍与使用
  5. Android JetPack~LiveData(二) 数据倒灌问题
  6. Android  JetPack~ ViewModel (一)   介绍与使用

1、数据倒灌的出现

场景:

如果我们在一个home页面获取网络数据,然后通过LiveData的观察者特性,在回调中跳转B页面,当旋转屏幕时,页面重建,LiveData又发来最后一次数据,那么直接触发了跳转B页面的代码。这就是数据倒灌引起的问题。因为LiveData的数据会保存在内存中。

数据倒灌原因:

个人描述:我们都知道LiveData是一个观察者模式,被观察者只要改变了观察者会收到通知。在页面重建时,LiveData自动推送最后一次数据供我们使用。 官方描述:ViewModel 将数据保留在内存中,这意味着开销要低于从磁盘或网络检索数据。ViewModel 与一个 Activity(或其他某个生命周期所有者)相关联,在配置更改期间保留在内存中,系统会自动将 ViewModel 与发生配置更改后产生的新 Activity 实例相关联。   在分发事件的时会先判断mVersion 和mLastVersion,当mLastVersion < mVersion时会onChanged((T) mData);进行分发。每次设置setValue时mVersion++,然后赋值给mLastVersion。
private abstract class ObserverWrapper {
    final Observer<? super T> mObserver;
    boolean mActive;
    // 第一处
    int mLastVersion = START_VERSION;
}
    private void considerNotify(ObserverWrapper observer) {
        ...
        // 第二处
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        // 第三处
        observer.mLastVersion = mVersion;
        observer.mObserver.onChanged((T) mData);
    }
从上面实验结果可知,屏幕旋转前,observer.mLastVersion == mVersion ==2。但是屏幕旋转后,mLastVersion的值却变成了-1。这里就是问题所在了。    

倒灌原因小结

Activity异常销毁然后重建,ViewModel会保存销毁之前的数据,然后在Activity重建完成后进行数据恢复,所以LiveData成员变量中的mVersion会恢复到重建之前的值。 但是Activity重建后会调用LiveData的observe()方法,方法内部会重新new一个实例,会将mLastVersion恢复到初始值。 由于LiveData本身的特性,Activity的生命周期由非活跃变成活跃时,LiveData会触发事件分发,导致屏幕旋转或者切换系统语言后出现数据倒灌。  

注意

但是这里有一点要非常注意:系统内存不足,杀到应用后台,也会导致Activity重建,但是不会LiveData导致数据倒灌。 问题找到了,那如何防止数据倒灌呢?

解决办法

再来回顾下,数据倒灌的常见方式:
  • 屏幕旋转
  • 用户手动切换系统语言
方案:
  • 如果应用不需要横屏,就设置为永久竖屏。
  • 如果当前Activity回到前台LiveData不需要接收最新的数据,可以使用下面三中扩展的LiveData

 

待续。。。。。

 

 

 

标签:JetPack,mVersion,LiveData,mLastVersion,倒灌,Android,数据
From: https://www.cnblogs.com/cmusketeer/p/17368277.html

相关文章

  • Android 开发入门(5)| 数据存储
    0x07数据存储(1)共享参数SharedPreferencesa.用法用法SharedPreferences是Android的一个轻量级存储工具,采用的存储结构为键值对的方式共享参数的存储介质是符合XML规范的配置文件,路径为/data/data/com.example.test/shared_prefs/xxx.xml使用场景简单且孤立的......
  • android5.0使用Notification报RemoteServiceException的解决办法
    有时android5.0下使用Notification会报如下错误信息(比如开启重启动系统就要发送通知)android.app.RemoteServiceException:Badnotificationpostedfrompackage*:Couldn'tcreateicon:StatusBarIcon这个问题多数集中在setSmallIcon(R.drawable.scan......
  • protobuf使用(一)android ndk 编译 protobuf-3.6.x windows
    首先建议大家看好版本,环境,有可能因为小的变化会造成编译有问题: 我的环境是PC OS:windows10(没办法暂时没机器);NDK:android-ndk-r17b-windows-x86_64ProtoBuf:protobuf-3.6.x  下载链接:https://github.com/protocolbuffers/protobuf/tree/3.6.x代码生成工具:protoc-3.6.1-wi......
  • Android换肤白天/夜间模式的框架
    Android换肤/夜间模式的Android框架,配合theme和换肤控件框架可以做到无缝切换换肤(无需重启应用和当前页面)。ThisframeworkofAndroidappsupportmultipletheme(suchasday/nightmode)andneedn’tfinishcurrentapplicationorcurrentactivity.......
  • [置顶] android点滴3
    Android判断是Pad或者手机publicbooleanisTabletDevice(){TelephonyManagertelephony=(TelephonyManager)getContext().getSystemService(Context.TELEPHONY_SERVICE);inttype=telephony.getPhoneType();if(type==TelephonyManager.PHON......
  • [置顶] android点滴1
    如何取得手机号码,手机串号,sim卡序列号?TelephonyManagertm=(TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);Stringdeviceid=tm.getDeviceId();Stringtel=tm.getLine1Number();//本机号码Stringimei=tm.getSimSerialN......
  • Android 方法引用数超过 65535 优雅解决
    随着应用不断迭代更新,业务线的扩展,应用越来越大(比如:集成了各种第三方SDK或者公共开源的Library文件、jar文件)这样一来,项目耦合性就很高,重复作用的类就越来越多了,SO:问题就来了。相信大家在做自己公司项目时,都有机会遇到下面的错误:UNEXPECTEDTOP-LEVELEXC......
  • Android为应用添加角标(Badge)
    1.需求简介角标是什么意思呢?看下图即可明了:可以看到图中的乐购这个app右上角的红色的圆圈,里面有10这个数字的,就是一种角标。角标,英语是badge,也就是“徽章,像章,奖章;象征,标记”的意思。一般来说,应用的角标是用来标记有多少条提醒(Notification)没读(unread),一旦......
  • android引用资源@与属性?备忘单
    几天前我偶然发现了我Android开发早期时制作的一份学习备忘单,是为理解如何处理Android资源和主题属性的语法而整理的。令人意外的是,我发现它对现在的我非常有用,因此决定整理成更适合博客的形式并分享给大家。知道我们今天要讨论的话题了,那么请看下面,通过x......
  • Android重力感应基础
    android中的很多游戏的游戏都使用了重力感应的技术,但其apidemo却并没有重力感应的实例(不知道是不是我没找到,找到的朋友麻烦告诉我一下,谢谢),因为开发的需要,就研究了一下重力感应这方面,因为网上关于这方面的东西比较少,所以写出来跟大家交流一下,算是抛砖引玉吧。(p......