【问题标题】:Can't observe correctly: viewLifecycleOwner vs this无法正确观察:viewLifecycleOwner vs this
【发布时间】:2021-01-13 06:50:17
【问题描述】:

让我们想象以下情况:我们有带有导航组件和 MVVM 架构的 BottomNavigationView。

在 Fragment 的这种情况下,这行代码现在可以工作

onViewCreated()

viewModel.isActionDone.observe(viewLifecycleOwner) {
    doReaction()
}

但是这段代码会吗?

private val observer = Observer<Boolean> {
    doReaction()
}

onViewCreated()

viewModel.isActionDone.observe(this, observer)

在我的应用程序中,第二个代码运行良好,但第一个代码运行不正常:当我移动到 BottomNavigationView 中的另一个元素时,观察者被多次调用。

附:此代码还多次调用观察者。

viewModel.isActionDone.observe(viewLifecycleOwner, observer)

你能帮我理解第一个代码有什么问题吗?

【问题讨论】:

标签: android kotlin android-livedata android-architecture-navigation android-mvvm


【解决方案1】:

这是因为每次在您的片段上调用 ​​onStart() 时,livedata 都会再次激活并再次发出最后一个值。您应该使用 Event 类作为包装器,或者您可以使用现在被认为是反模式的 SingleLiveEvent 类。 您可以阅读此内容以获取更多信息:https://medium.com/androiddevelopers/livedata-with-snackbar-navigation-and-other-events-the-singleliveevent-case-ac2622673150

【讨论】:

  • it's because every time onStart() is called on your fragment, the livedata becomes active again and emits the last value again 这不是真的
  • @IR42 是的,这是真的
  • SingleLiveEvent 自 2018 年左右开始成为官方反模式
  • @EpicPandaForce 是的,那时我还不是开发人员:D
【解决方案2】:

这是因为当你移动到另一个fragment时,NavController会销毁视图并停止fragment,当你回到第一个fragment时,会启动fragment并再次创建视图。

因此,当您使用“viewLifecycleOwner”进行观察时,每次返回第一个片段时,您的 LiveData 都会发出最后一个值。但是当使用“this”时,它不会。

因此,您应该考虑每次创建视图或每次创建片段时都需要发出的业务,并使用合适的 LifecycleOwner。

我家它帮你。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-17
    • 2020-10-09
    • 2020-05-13
    • 2013-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多