Наблюдение за 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).