У меня есть отдельный класс, в котором я обрабатываю выборку данных (в частности, Firebase), и я обычно возвращаю объекты LiveData из нее и обновляю их асинхронно. Теперь я хочу, чтобы возвращаемые данные хранились в ViewModel, но проблема в том, что для получения упомянутого значения мне нужно наблюдать объект LiveData, возвращенный из класса извлечения данных. Метод наблюдения требовал, чтобы объект LifecycleOwner был первым параметром, но я, очевидно, не имею этого внутри моего ViewModel, и я знаю, что я не должен хранить ссылку на Activity/Fragment внутри ViewModel. Что мне делать?
Наблюдение LiveData из ViewModel
Ответ 1
В этом сообщении в блоге от разработчика Google Хосе Алькерреки рекомендуется использовать преобразование в этом случае (см. Параграф "LiveData in repositories").
Ответ 2
В документации ViewModel
Однако объекты ViewModel никогда не должны наблюдать изменения в наблюдаемых жизненных циклах объектах, таких как объекты LiveData.
Другой способ заключается в том, что данные реализуют RxJava, а не LiveData, тогда преимущество в том, что они будут учитывать жизненный цикл.
В примере Google todo-mvvm-live-kotlin он использует обратный вызов без LiveData во ViewModel.
Я предполагаю, что если вы хотите полностью соответствовать идее жизненного цикла, нам нужно переместить код наблюдения в Activity/Fragment. Иначе, мы можем использовать callback или RxJava во ViewModel.
Другим компромиссом является реализация MediatorLiveData (или Transformations) и наблюдение (поместите свою логику здесь) в ViewModel. Обратите внимание, что наблюдатель MediatorLiveData не сработает (так же, как Transformations), если он не обнаружен в 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: Patterns + AntiPatterns, которые предлагали трансформации. Я не думаю, что это работает, если не наблюдаются LiveData (что, вероятно, требует, чтобы это было сделано в Activity/Fragment).
Ответ 3
Это старый вопрос. Но можно использовать MediatorLiveData
см. документацию MediatorLiveData
Ответ 4
Я думаю, что вы можете использовать applyForever, для которого не требуется интерфейс владельца жизненного цикла, и вы можете наблюдать результаты из модели представления