我将导航底部与共享viewmodel一起使用,并且所有片段都位于导航底部,但是第二次调用片段时会抛出此异常
java.lang.IllegalArgumentException:无法添加具有不同生命周期的同一观察者
我试图让所有观察者都附属于活动而不是活动的片段 如下
1-在fragemt中声明viewModel
viewModel = activity?.run {
ViewModelProviders.of(this,viewModelFactory).get(SharedViewModel::class.java)
} ?: throw Exception("Invalid Activity")
2-Observer livedata对象
viewModel.msg.observe(activity!!, Observer {
Log.i(TAG,it)
})
3-删除观察者
override fun onStop() {
super.onStop()
viewModel.msg.removeObservers(activity!!)
}
此代码对我来说很好用,但是我想知道我的代码是否正确并且可以工作吗? 预先感谢
答案 0 :(得分:1)
这是我们在片段中使用实时数据时常犯的错误。在片段上使用this
/ activity
可以重复。您应该使用viewLifecycleOwner
片段中的实时数据观察。
viewModel.msg.observe(viewLifecycleOwner, Observer {
Log.i(TAG,it)
})
有关更多信息,请阅读本文https://medium.com/@cs.ibrahimyilmaz/viewlifecycleowner-vs-this-a8259800367b
您不需要手动删除观察者。
答案 1 :(得分:0)
为什么要将观察者添加到具有活动生命周期的片段中?如果片段处于非活动状态时需要执行某些逻辑,请将其添加到活动中。因此,除了需要的东西之外,您还需要:
viewModel.msg.observe(this, Observer {
Log.i(TAG, it)
})
在您的情况下发生的情况是,每次重新打开片段时,您都将以相同的生命周期附加一个新的观察者,这似乎是一个错误。 Livedata观察器经过专门设计,因此您不必编写用于手动处理生命周期的代码。