首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么当多次调用setValue()时,MutableLiveData观察者只调用一次?

当多次调用setValue()时,MutableLiveData观察者只会被调用一次的原因是因为MutableLiveData在默认情况下,会将相同的数据值视为相同的事件,只有当数据值发生变化时,观察者才会被通知。

MutableLiveData是一种可观察的数据持有类,它可以存储任意类型的数据,并在数据发生变化时通知观察者。当我们调用setValue()方法来更新MutableLiveData的值时,如果新值与旧值相同,观察者不会被通知。这是因为MutableLiveData会对新旧值进行比较,只有在值发生变化时才会触发观察者的回调。

这种设计有助于避免不必要的观察者回调,提高性能和效率。例如,在某些情况下,我们可能会在数据源发生变化时频繁地调用setValue()方法,但只有当实际的数据值发生变化时,观察者才需要进行相应的处理。通过只在值发生变化时通知观察者,可以避免不必要的重复操作。

然而,如果我们希望每次调用setValue()时都能触发观察者的回调,而不仅仅是在值发生变化时,可以使用postValue()方法来替代setValue()方法。postValue()方法会将数据更新操作放入主线程的消息队列中,确保观察者在下一次消息循环中被通知,即使新值与旧值相同也会触发观察者的回调。

总结起来,MutableLiveData观察者只在数据值发生变化时被调用,这是为了提高性能和效率。如果需要每次调用setValue()都触发观察者的回调,可以使用postValue()方法来实现。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

Android  JetPack~ LiveData (一)   介绍与使用

从非活跃状态变为活跃状态,回调方法会立即接收到最新的数据 设备切横竖屏,会重建Activity生命周期,它也会立即接收最新的可用数据。...postValue()   postValue的特性如下:   1.此方法可以在其他线程中调用   2.如果在主线程执行发布的任务之前多次调用此方法,则仅将分配最后一个值。   ...3.如果同时调用 .postValue()和.setValue(),结果是post的值覆盖set值。...setValue()   setValue()的特性如下:   1.此方法只能在主线程里调用 getValue()   返回当前值。 注意,在后台线程上调用此方法并不能保证将接收到最新的值。...super T> observer)   设置此LiveData数据当前activity或者Fragment的观察者,会给此activity或者Fragment在前台回调数据。

1.5K20
  • Android程序员该如何去手写事件通信方案LiveDataBus

    2.减少内存泄漏 这是因为LiveData能够感知到组件的生命周期,组件处于DESTROYED状态观察者对象会被清除掉。...3.Activity停止不会引起崩溃 这是因为组件处于非激活状态,不会收到LiveData中数据变化的通知。...6.针对configuration change,不需要额外的处理来保存数据 我们知道,当你把数据存储在组件中configuration change(比如语言、屏幕方向变化),组件会被recreate...根据Fragment/Activity生命周期发生变化时,移除观察者或者通知观察者更新数据。 调用LiveData的setValue()、postValue()方法后,通知观察者更新数据。...MutableLiveData是LiveData的子类,添加了公共方法setValue和postValue,方便开发者直接使用。setValue必须在主线程调用

    1.4K10

    Jetpack之LiveData详解

    在给 LiveData 添加观察者对象的时候可以绑定一个具有生命周期的组件,组件生命周期处于活跃状态(即 STARTED 、RESUMED 状态)时数据更新才会通知观察者组件被销毁则会自动移除对应的观察者对象...容器的数据 protected void onActive():活跃的观察者对象数量大于 0 时调用,即有活跃的观察者对象时调用 protected void onInactive():活跃的观察者对象数量等于...0 时调用,即无活跃的观察者对象时调用 MutableLiveData:可变的 LiveData,是我们最常用的 LiveData 子类。...() liveData.observeForever { //do something } 这种情况不需要进行观察的时候就需要手动调用 removeObserver 将观察者移除...setValue 方法当前版本 mVersion++,最后则是调用观察者的回调,即我们传入的 Observer 的 onChanged 方法。

    1.7K20

    Android Jetpack架构组件(四)之LiveData

    LiveData是一个持有数据的容器类,它持有的数据是可以被观察者订阅的,数据发生变化时会通知观察者观察者可以是 Activity、Fragment、Service 等对象。...使用 LiveData 保存数据,由于数据和组件是分离的,所以组件被销毁可以保证数据不会丢失。...因此,我们认为LiveData就是一个数据容器,它负责将数据包裹起来,使数据成为被观察者数据发生变化时,LiveData会通知观察者以便观察者做出响应。...setValue():注意到value=price这里是调用setValue(price)方法,通过该方法更新LiveData的值,进而通知处于活跃状态的订阅者。...,会调用onStateChanged方法,组件处于DESTROYED状态,会调用removeObserver方法移除observer。

    3K00

    事件总线方案实践

    发布: 发布者通过 getChannel() 获取消息通道,然后调用 setValue() 或者 postValue() 发布消息。...- 2.多次调用了 postValue() 方法,只有最后次调用的值会得到更新。也就是此方法是有可能会丢失事件!...dispatchingValue的情况 // 对应数据的观察者在执行的过程中, 如有新的数据变更, 则不会再次通知到观察者。...#### 7.2 然后看一下第二个问题 - 首先看一下postValue源代码,如下所示: - 看代码注释中说,如果在多线程中同一个时刻,多次调用了 postValue() 方法,只有最后次调用的值会得到更新...然后往主线程抛一个 Runnable,在这个 Runnable 里面再调用 setValue 来把存起来的值真正设置上去,并回调观察者们。

    1.9K30

    Android从零开始搭建MVVM架构(4)——LiveData

    通常情况下,LiveData在数据有变化时,给活跃的Observer进行通知。 此行为的一个例外是,Observer在从非活跃状态变为活跃状态也会收到通知。...更新数据库,会生成所有必要的代码来更新LiveData对象。 生成的代码在需要在后台线程上异步运行查询。 这种模式对于保持用户界面中显示的数据与存储在数据库中的数据同步很有用。...LiveData对象没有任何活跃的Observer,onInactive()方法被调用。 由于没有Observer在监听,所以没有理由继续保持与StockManager服务的连接。...setValue(T)方法更新LiveData实例的值,并通知活动观察者有关更改。...LiveData在他们至少一个处于可见和活跃状态才连接到系统服务。

    2.3K30

    LiveData的前世今生

    例如:一个值可以在没有观察者活动的情况下被设置,所以新的观察者会直接取代它。另外,从不同的线程设置值可能会导致竞赛条件,产生一个对观察者调用。...它是一个LiveData,但发送一次更新。...如果你不小心增加了一个以上的观察者,只有一个会被调用,而且不能保证是哪一个。...确保你的用户界面与你的数据状态相匹配:LiveData遵循观察者模式,生命周期状态改变,LiveData会通知观察者对象。你可以整合你的代码来更新这些观察者对象中的UI。...你的观察者可以在每次应用数据变化(生命周期变化)更新UI,而不是在每次有变化时更新UI。 没有内存泄漏:观察者被绑定到生命周期对象,并在其相关的生命周期被销毁进行自我清理。

    1.1K10

    LiveData 还有学习的必要吗?—— Jetpack 系列(2)

    宿主生命周期进入消亡(DESTROYED)状态,LiveData 会自动移除观察者,避免内存泄漏; 2、安全地回调数据: 在宿主生命周期状态低于活跃状态(STAETED),LiveData 不会回调数据...,观察者绑定的生命处于活跃状态,并且 LiveData 存在已设置的旧数据; 2、调用 setValue() / postValue() 设置数据观察者绑定的生命周期处于活跃状态; 3、观察者绑定的生命周期由非活跃状态转为活跃状态...而观察者的持有的初始版本号是 -1,因此注册新观察者并且正好宿主的生命周期是大于等于可见状态(STARTED),就会尝试分发数据,这就是数据重放。...LiveData 重放问题需要区分场景来看 —— 状态适合重放,而事件不适合重放: LiveData 作为一个状态使用时,在注册新观察者重放已有状态是合理的; LiveData 作为一个事件使用时...这样的话,观察者收到重放的数据,由于其中的标记位已经显示被消费,因此会抛弃该事件。

    3.6K10

    谷歌官方Android应用架构库——LiveData

    LiveData 有一个处于活动状态的观察者该方法被调用,这意味着需要开始从设备观察位置更新。...vonInactive(): LiveData 没有任何处于活动状态的观察者该方法被调用。由于没有观察者在监听,所以没有理由保持与 LocationManager 的连接。...setValue():调用该方法更新 LiveData 实例的值,并将此变更通知给处于活动状态的观察者。...资源共享:可以保留一个 MyLocationListener 实例,连接系统服务一次,并且能够正确的支持应用程序中的所有观察者。...postalCode 被定义为 addressInput 的转换,所以 addressInput 改变,如果有处于活动状态的观察者,repository.getPostCode() 将会被调用

    1.1K30

    带你了解LiveData重放污染的前世今生

    然而,有些数据应该被消耗一次,比如说Snackbar消息、导航事件或对话框类似的场景。 与其试图用库或架构组件来解决这个问题,不如把它作为一个设计问题来面对。...例如:一个值可以在没有观察者活动的情况下被设置,所以新的观察者会直接取代它。另外,从不同的线程设置值可能会导致竞赛条件,产生一个对观察者调用。...它是一个LiveData,但发送一次更新。...如果你不小心增加了一个以上的观察者,只有一个会被调用,而且不能保证是哪一个。...确保你的用户界面与你的数据状态相匹配:LiveData遵循观察者模式,生命周期状态改变,LiveData会通知观察者对象。你可以整合你的代码来更新这些观察者对象中的UI。

    1.2K10

    【AAC 系列三】深入理解架构组件:LiveData

    释义: 定义一个 MutableLiveData (LiveData 的一个常用子类),通过 observe 方法可以订阅修改数据的通知,通过 postValue()或者 setValue() 方法可以更新数据...setValue 方法,注意 setValue 必须是在主线程调用。...4.1 Sticky Event LiveData 被订阅,如果之前已经更改过数据,并且当前 owner 为 active 的状态,activeStateChanged() 会被调用,也即会立马通知到...setValue 只不过把操作放到主线程,适合在异步线程里调用setValue 必须在主线程里调用; 如果同时多次调用 postValue 或 setValue 修改数据,只会修改成最新的那个数据,...也即只会收到一次通知(set post混合调用则不一定); 如果 LiveData 有数据,并且 owner 在 active 状态下,那么在订阅的时候,会立马收到一次通知; 一个 Observer 实例

    90620

    Jetpack—LiveData组件的缺陷以及应对策略

    官网商城app团队在深度使用LiveData的过程中,也遇到了一些困难,尤其是在LiveData的观察者使用上踩到了不少坑,我们把这些经验在这里做一次总结与分享。...二、Observer到底可以接收多少次回调 2.1 为什么最多收到2个通知 这是一个典型的案例,在调试消息总线的场景,我们通常会在消息的接收者那里打印一些log日志方便我们定位问题,然而日志的打印有时候也会给我们的问题定位带来一定的迷惑性...10个观察者,但是收到了2个回调通知?...经过一次setValue以后她的值就变成了0。 后续每次observe的时候会创建一个ObserverWrapper。...这里也一样,我们可以尝试“一个消息被消费一次”的思路来解决上述的问题。

    1.2K20

    Android消息总线的演进之路:用LiveDataBus替代RxBus、EventBus

    观察者的生命周期处于STARTED或RESUMED状态,LiveData会通知观察者数据变化;在观察者处于其他状态,即使LiveData的数据变化了,也不会通知。...避免内存泄漏,观察者被绑定到组件的生命周期上,被绑定的组件销毁(destroy)观察者会立刻自动清理自身的数据。...不会再产生由于Activity处于stop状态而引起的崩溃,例如:Activity处于后台状态,是不会收到LiveData的任何事件的。...发布 发布者通过getChannel获取消息通道,然后调用setValue或者postValue发布消息。 LiveDataBus原理图 ?...对于LiveData,其初始的version是-1,当我们调用了其setValue或者postValue,其vesion会+1;对于每一个观察者的封装ObserverWrapper,其初始version

    2.3K30
    领券