繁体   English   中英

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

[英]LiveData observer fired twice, even with viewLifecycleOwner

我正在与一个LiveData观察器挣扎,它会触发两次。 在我的片段中,我使用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)
} 

这是我的视图模型:

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)
            }
        }
    }

}

第一次运行该片段时,一切正常,但是,当我转到其DetailFragment并返回时,将两次触发retailLiveData Observer回调。 根据本文,这是一个已知问题,可以通过引入viewLifeCycleOwner来解决,一旦破坏了片段的视图,该视图将有助于移除活动的观察者,但是对于我来说似乎没有帮助。

发生这种情况的原因是,当您打开另一个片段时,视图模型保留了价值,但是该片段的视图被破坏了。 当您回到片段时,将重新创建视图,并且您订阅了retailLiveData ,该片段仍保留先前的值,并在片段进入开始状态时立即通知您的观察者。 但是您要在onViewCreated中调用retailViewModel.getRetailById(retail.id) ,因此一段时间后,值会更新,并且观察者会再次收到通知。

一种可能的解决方案是从视图模型的init方法调用getRetailById() ,然后将结果缓存为视图模型的生存期。

暂无
暂无

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

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