Android livedata观察事件在每个片段启动时触发

Android livedata观察事件在每个片段启动时触发,android,kotlin,fragment,android-livedata,mutablelivedata,Android,Kotlin,Fragment,Android Livedata,Mutablelivedata,我对LiveData有问题 我有3个片段A(menuFragment)、B(doThingsFragment)、C(displayMessageFragment)。 我们可以从A移到B,从B移到C,最后从C移到A 在doThingsFragment的onStart方法上,我从doThingsViewModel观察LiveData,当该值更改时,我移动到displayMessageFragment doThingsViewModel: private var _message : MutableL

我对LiveData有问题

我有3个片段A(menuFragment)、B(doThingsFragment)、C(displayMessageFragment)。 我们可以从A移到B,从B移到C,最后从C移到A

在doThingsFragment的onStart方法上,我从doThingsViewModel观察LiveData,当该值更改时,我移动到displayMessageFragment

doThingsViewModel:

private var _message : MutableLiveData<String> = MutableLiveData()
var message : LiveData<String> = _message 

fun someFunction() {
    _message.value = "blablabla"
}
override fun onStart() {
    super.onStart()

    mViewModel!!.message.observe(
        viewLifecycleOwner,
        Observer<String>
        {
            msg ->
            if(!msg.isNullOrEmpty() && mViewModel!!.toastType.value != null){
                val args = Bundle()
                args.putString("message", msg)

                Navigation.findNavController(requireView()).navigate(R.id.mountUnmountValidationFragment, args)
            }
        })
}
private var\u消息:MutableLiveData=MutableLiveData()
var消息:LiveData=\u消息
有趣的功能(){
_message.value=“blabla”
}
doThingsFragment:

private var _message : MutableLiveData<String> = MutableLiveData()
var message : LiveData<String> = _message 

fun someFunction() {
    _message.value = "blablabla"
}
override fun onStart() {
    super.onStart()

    mViewModel!!.message.observe(
        viewLifecycleOwner,
        Observer<String>
        {
            msg ->
            if(!msg.isNullOrEmpty() && mViewModel!!.toastType.value != null){
                val args = Bundle()
                args.putString("message", msg)

                Navigation.findNavController(requireView()).navigate(R.id.mountUnmountValidationFragment, args)
            }
        })
}
override-fun-onStart(){
super.onStart()
mViewModel!!.message.observe(
viewLifecycleOwner,
观察者
{
味精->
如果(!msg.isNullOrEmpty()&&mViewModel!!.toastType.value!=null){
val args=Bundle()
args.putString(“消息”,msg)
Navigation.findNavController(requireView()).navigate(R.id.mountmountvalidationfragment,args)
}
})
}
在我第一次更新_消息时,它工作得非常好(我们按照预期从B到C)。 然而,当我再次尝试从A移动到B时,我们再次进入doThingsFragment观察器回调,在显示片段B之前,我继续移动到片段C

由于_message值没有更改,因此我希望每次调用doThingFragment.onStart方法时都不会触发观察者回调…

我错过了什么


非常感谢

这是livedata的行为方式,如果您只需要一次receiver event,google或stackoverflow about
SingleLiveData
livedata
在观察者模式下工作,在观察者模式下,某个对象注册为观察者,每次观察到的对象发生变化时,它都会收到通知。它值得:

在给定所有者的生命周期内,将给定的观察者添加到观察者列表中。事件在主线程上调度如果LiveData已经有数据集,它将被交付给观察者

当数据在所有者[
LifecycleOwner
]未激活时发生更改时,例如,
活动
]将不会收到任何更新。如果它再次激活,它将自动接收最后可用的数据

这些是重要的一点-当您注册到
观察数据时,您将立即收到最新值的通知(如果有),而不仅仅是在发生更改时。因此,您不能依赖回调触发作为需要从
B
移动到
C
的信号

你实际需要做什么取决于你的应用程序逻辑,你如何区分“刚刚显示的片段B,这是一个值,现在我需要显示片段C”和“刚刚显示的片段B,这是一个值,但我碰巧知道这次我不需要显示片段C”。您可以在第一次收到某些数据时设置
Initialized
标志(可能需要将该状态保留在
onSaveInstanceState
)或保留上次看到的值(更难保留),但您知道了