Android LiveData наблюдает устаревшие данные после перехода назад - PullRequest
0 голосов
/ 28 октября 2018

Вопрос:

Как я могу предотвратить немедленное получение моими данными устаревших данных при навигации назад?Я использую класс 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()
}

1 Ответ

0 голосов
/ 20 ноября 2018

Хорошо, здесь есть две проблемы, которые, я надеюсь, помогут кому-то еще.

  • Во-первых, класс Event не работает с преобразованиями.Я думаю, это потому, что Событие в буквальном смысле указывает на неправильные данные в реальном времени (_login_credentials против user)
  • Вторая проблема немного более фундаментальна, но в настоящее время ослепительно очевидна.Нам повсюду сообщают, что наблюдения за данными в реальном времени генерируют самые последние данные при оформлении подписки, чтобы вы могли получать самые свежие данные.Это означает, что способ использования живых данных здесь просто неправильный, я не могу подписаться на событие входа в систему, перейти куда-либо, перейти назад и повторно подписаться, потому что ViewModel по праву предоставляет мне последние данные, которые у него есть (потому что фрагмент входа в системубыл только отсоединен, но не уничтожен).

Решение

Решение состоит в том, чтобы просто переместить логику, которая выполняет выборку на один фрагмент глубже.Поэтому вместо того, чтобы прослушивать учетные данные пользователя + щелчок при входе в систему -> выбор пользователя -> и затем перемещаться куда-то, мне нужно прослушать учетные данные пользователя + щелчок при входе в систему -> перейти куда-нибудь -> и , а затем начать подписку на мойПользовательские данные в реальном времени.Таким образом, я могу вернуться к экрану входа в систему столько, сколько захочу, и не подписываться на устаревшие данные, которые никогда не уничтожались.И если я вернусь к входу в систему, а затем переадресую, подписка и фрагмент будут уничтожены, поэтому я соответствующим образом получу новые данные в этом случае.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...