Приложение зависает, когда LiveData присваивается нулевое значение

У меня есть LiveData с именем navigationArgs:

private val _navigationArgs = MutableLiveData<Item>()
val navigationArgs: LiveData<Item>; get() = _navigationArgs

в котором хранятся аргументы, которые будут переданы следующему фрагменту. Он прикреплен к наблюдателю для навигации при изменении значения:

viewModel.navigationArgs.observe(this, Observer{
 //navigation code
 viewModel.finishedNavigating()
})

в котором в finishNavigating() значение _navigationArgs установлено равным нулю:

fun finishedNavigating(){
 _navigationArgs.value = null
}

При включении finishedNavigating() в обозревателе приложение зависает даже без навигации при изменении значения _navigationArgs.

Почему это происходит? Я использую Android Studio 4.0 Canary. Спасибо.


person LCZ    schedule 24.11.2019    source источник
comment
if (it != null) viewModel.finishedNavigating() Попробуйте это   -  person Amin Pinjari    schedule 24.11.2019


Ответы (2)


Когда вы присваиваете что-то _navigationArgs.value, в Observer автоматически вызывается код, который используется в viewModel.navigationArgs.observe (navigationArgs и _navigationArgs - это одни и те же объекты, потому что navigationArgs имеет геттер, который возвращает _navigationArgs ).

В вашем случае вы назначаете null _navigationArgs.value в finishedNavigating(), который вызывает код в Observer, который снова вызывает finishedNavigating() и т. д.

У вас просто рекурсия здесь.

Вы должны добавить условие выхода рекурсии. Например:

viewModel.navigationArgs.observe(this, Observer{
 //navigation code
 if (it != null) //don't call finishedNavigating, when null passed in to _navigationArgs.value
  viewModel.finishedNavigating()
})
person Andrew    schedule 24.11.2019
comment
Большое спасибо. Это решение сработало. Вместо этого я окружил код навигации и finishedNavigating() в it?.let{...}. - person LCZ; 24.11.2019
comment
Я думаю, что мы не должны выполнять вычисления внутри Observer. Ответственность ViewModel должна заключаться в обработке нулевой проверки и соответствующей передаче значения. - person Ishtdeep Hora; 24.11.2019
comment
Да, но код навигации включает в себя аргументы навигации, переданные следующему фрагменту, и если в Observer не была сделана проверка на null, то будет выдана ошибка, так как в аргументы кода навигации будет передано null, в котором Item ожидал. - person LCZ; 26.11.2019

ммм, это похоже на бесконечный цикл значений, отправляемых наблюдателю, каждый раз, когда вы устанавливаете значение, отправляется ноль, а затем снова и снова.

person Ignacio Tomas Crespo    schedule 24.11.2019