簡體   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