简体   繁体   English

即使使用viewLifecycleOwner,LiveData观察器也会触发两次

[英]LiveData observer fired twice, even with viewLifecycleOwner

I'm struggling with a LiveData observer which is firing twice. 我正在与一个LiveData观察器挣扎,它会触发两次。 In my fragment I'm observing a LiveData as below, using viewLifeCycleOwner as LifeCycleOwner 在我的片段中,我使用viewLifeCycleOwner作为LifeCycleOwner来观察LiveData ,如下所示

private lateinit var retailViewModel: RetailsViewModel

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        retailViewModel =  ViewModelProviders.of(this).get(RetailsViewModel::class.java)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

  retailViewModel.retailLiveData.observe(viewLifecycleOwner, Observer {
    // updating UI here, but firing twice!
  }

  retailViewModel.getRetailById(retail.id)
} 

And this is my view model: 这是我的视图模型:

class RetailsViewModel(override val service: MyFoodyApiService = MyFoodyApiService.service) :
    BaseViewModel(service) {

    var retailLiveData: MutableLiveData<Retail> = MutableLiveData()

    fun getRetailById(id: Int) {
        scope.launch {
            try {
                val response =
                    service.getRetailById(authString, id).await()
                when (response.isSuccessful) {
                    true -> {
                        response.body()?.let { payload ->
                            retailLiveData.postValue(payload.data)
                        } ?: run {
                            errorLiveData.postValue("An error occurred: ${response.message()}")
                        }
                    }
                    false -> errorLiveData.postValue("An error occurred: ${response.message()}")
                }
            } catch (e: Exception) {
                noConnectionLiveData.postValue(true)
            }
        }
    }

}

When I run the fragment for the first time, everything works fine, however when I go to its DetailFragment and come back, retailLiveData Observer callback is fired twice. 第一次运行该片段时,一切正常,但是,当我转到其DetailFragment并返回时,将两次触发retailLiveData Observer回调。 According to this article this was a known problem solved with the introduction of viewLifeCycleOwner who should be helpful to remove active observers once fragment's view is destroyed, however it seems not helping in my case. 根据本文,这是一个已知问题,可以通过引入viewLifeCycleOwner来解决,一旦破坏了片段的视图,该视图将有助于移除活动的观察者,但是对于我来说似乎没有帮助。

This happens because view model retains value when you open another fragment, but the fragment's view is destroyed. 发生这种情况的原因是,当您打开另一个片段时,视图模型保留了价值,但是该片段的视图被破坏了。 When you get back to the fragment, view is recreated and you subscribe to retailLiveData , which still holds the previous value and notifies your observer as soon as fragment moves to started state. 当您回到片段时,将重新创建视图,并且您订阅了retailLiveData ,该片段仍保留先前的值,并在片段进入开始状态时立即通知您的观察者。 But you are calling retailViewModel.getRetailById(retail.id) in onViewCreated , so after awhile the value is updated and observer is notified again. 但是您要在onViewCreated中调用retailViewModel.getRetailById(retail.id) ,因此一段时间后,值会更新,并且观察者会再次收到通知。

One possible solution is to call getRetailById() from view model's init method, the result will be cached for view model lifetime then. 一种可能的解决方案是从视图模型的init方法调用getRetailById() ,然后将结果缓存为视图模型的生存期。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM