簡體   English   中英

向后導航后,Android LiveData會觀察到過時的數據

[英]Android LiveData observes stale data after navigating back

題:

向后導航時,如何防止livedata立即接收過時的數據? 我正在使用此處概述的Event類,我認為這可以防止這種情況。

問題:

我用一個登錄片段打開該應用程序,並在設置了實時數據電子郵件/密碼后導航到一個注冊片段(后端調用顯示“這是一個新帳戶,請注冊”)。 如果用戶在注冊過程中按下了“后退”按鈕,則Android將彈出登錄。 當按下返回鍵后重新創建登錄片段時,它將立即使用陳舊的后端響應再次觸發實時數據,我想防止這種情況發生。

LoginFragment.kt

  override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    subscribeToLoginEvent()
}

private fun subscribeToLoginEvent() {
    //When a back press occurs, we subscribe again and this instantly 
    //fires with the same data it used to leave the screen 
    //(a Resource<User> with status=SUCCESS, data = null)

    viewModel.user.observe(viewLifecycleOwner, Observer { response ->
        Timber.i("login event observed....status:" + response?.status + ", data: " + response?.data)
        binding.userResource = response

        response?.let {
            val status = it.status
            val message = it.message

            if (status == Status.SUCCESS && it.data == null) {
                //This is a brand new user so we need to register now 
                navController()
                .navigate(LoginFragmentDirections.showUserRegistration()))
            }
            else if(status == Status.SUCCESS && it.data != null){
                goHome()
            }
        }
    })
}

LoginViewModel.kt

private val _loginCredentials: MutableLiveData<Event<Pair<String, String>>> = MutableLiveData()

val user: LiveData<Resource<User>> = Transformations.switchMap(_loginCredentials) {
    val data = it.getContentIfNotHandled()
    if(data != null && data.first.isNotBlank() && data.second.isNotBlank())
        interactor.callUserLoginRepo(data.first, data.second)
    else
        AbsentLiveData.create()
}

好的,這里有兩個問題,希望對其他人有所幫助。

  • 首先是Event類似乎不適用於轉換。 我認為這是因為該事件實際上是指向錯誤的實時數據( _login_credentialsuser
  • 第二個問題是更根本的問題,但現在也非常明顯。 訂閱后,我們會被告知各地實時數據觀測會發出最新數據,以確保您獲得最新數據。 這意味着我在這里使用實時數據的方式是完全錯誤的,我無法訂閱登錄事件,無法導航,無法導航並重新訂閱,因為ViewModel正確地向我提供了它擁有的最新數據(因為登錄片段只是超脫,從未被摧毀)。

解決方案是簡單地移動執行提取一個片段的邏輯的深度。 因此,除了偵聽用戶憑據+登錄單擊->獲取用戶->然后導航至某個地方,我需要偵聽用戶憑據+登錄單擊->導航至某地方-> 然后開始訂閱用戶實時數據。 這樣,我可以盡可能多地返回登錄屏幕,而不必訂閱一些從未破壞的過時的實時數據。 如果我返回登錄然后轉發,則預訂和片段被破壞,因此在這種情況下,我將適當地獲取新數據。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM