Наблюдение за LiveData из ViewModel
У меня есть отдельный класс, в котором я обрабатываю выборку данных (в частности, Firebase), и я обычно возвращаю объекты LiveData из него и обновляю их асинхронно. Теперь я хочу, чтобы возвращенные данные хранились в ViewModel, но проблема в том, что для получения указанного значения мне нужно наблюдать объект LiveData, возвращенный из моего класса извлечения данных. Метод observe требовал объекта LifecycleOwner в качестве первого параметра, но у меня, очевидно, нет этого внутри моей ViewModel и I знайте, что я не должен хранить ссылку на активность / фрагмент внутри ViewModel. Что мне делать?
2 ответов
на этот блог разработчиком Google Jose Alcérreca в этом случае рекомендуется использовать преобразование (см. пункт "LiveData в репозиториях").
на ViewModel документация
однако объекты ViewModel никогда не должны наблюдать изменения в наблюдаемых объектах с учетом жизненного цикла, таких как объекты LiveData.
другой способ заключается в том, чтобы данные реализовывали RxJava, а не LiveData, тогда он не будет иметь преимущества быть в курсе жизненного цикла.
в образце google todo-mvvm-live-Котлин, он использует обратный вызов без LiveData в ViewModel.
Я если вы хотите соответствовать всей идее жизненного цикла, нам нужно переместить код наблюдения в Activity / Fragment. В противном случае мы можем использовать обратный вызов или RxJava в ViewModel.
другой компромисс-реализовать MediatorLiveData (или преобразования) и наблюдать (поместите свою логику здесь) в ViewModel. Уведомление MediatorLiveData observer не будет запускаться (так же, как преобразования), если это не наблюдается в Activity/Fragment. Что мы делаем, так это помещаем пустое наблюдение в Activity / Fragment, где реальная работа фактически выполняется в ViewModel.
// ViewModel
fun start(id : Long) : LiveData<User>? {
val liveData = MediatorLiveData<User>()
liveData.addSource(dataSource.getById(id), Observer {
if (it != null) {
// put your logic here
}
})
}
// Activity/Fragment
viewModel.start(id)?.observe(this, Observer {
// blank observe here
})
PS: Я читал ViewModels и LiveData: Шаблоны + антипаттерны который предположил, что преобразования. Я не думаю, что это работает, если LiveData не наблюдается (что, вероятно, требует, чтобы это было сделано в Activity/Fragment).