Как заставить viewmodel наблюдать за хранилищем без объекта жизненного цикла - PullRequest
0 голосов
/ 09 июля 2019

Я создаю приложение для Android с дизайном MVVM, и у меня есть несколько слоев (view, ViewModel, репозиторий и источник данных как локальный, так и удаленный). Я хочу, чтобы мой объект репозитория наблюдал источники данных, выполнял всю его логику для того, как и при хранении кэша, отображал данные в правильную форму для указанного выше слоя и только затем уведомлял модель представления о новых данных.

Аналогично тому, что я хочу, чтобы ViewModel наблюдал за хранилищем для поступления новых данных, затем выполнял всю бизнес-логику и только после этого уведомлял представление.

Моя проблема в том, что LiveData требует объекта жизненного цикла, который ViewModel и хранилище не имеет.

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

Я также читал об использовании Transformations.map, но что, если я не хочу отображать данные, а делать что-то более сложное.

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

примечание: моя ViewModel используется в нескольких фрагментах, если это как-то актуально.

Ответы [ 3 ]

1 голос
/ 09 июля 2019

Моя проблема в том, что LiveData требует объект жизненного цикла

На самом деле, жизненный цикл не является обязательным. В LiveData есть метод observeForever(Observer), который не требует жизненного цикла. Но это означает, что вы также должны вручную вызвать removeObserver(Observer), когда ваш репозиторий завершит работу, иначе это будет утечка.
Это на самом деле мало чем отличается от использования наблюдаемых Rx. В обоих случаях вы должны переопределить onCleared() в вашей модели представления и вручную отписаться (или удалить наблюдателя) из хранилища.

наблюдаемые живы вечно, и это может привести к странным сбоям

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

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

Как вы и написали, вы пытаетесь создать объект Data View, который наблюдает, ViewModel, который наблюдает, репо, который наблюдает, DataSource. Это уже цепь, с ней надо разобраться.

Можно безопасно наблюдать LiveData из ViewModel, поскольку View имеет жизненный цикл, а LiveData имеет наблюдение с учетом жизненного цикла.
Но у Repo и DataSource нет жизненных циклов, поэтому вы должны вручную управлять подписками. Это возможно как с помощью LiveData, так и наблюдаемых Rx - вы можете выбрать любой, какой пожелаете.

0 голосов
/ 09 июля 2019

Вы можете использовать DataBinding для отображения данных ViewModel в вашем пользовательском интерфейсе. https://developer.android.com/topic/libraries/data-binding

Дополнительным преимуществом является то, что вы пишете меньше стандартного кода.

0 голосов
/ 09 июля 2019

1. Прежде всего, если вам нужен контекст в viewmodel, используйте AndroidViewModel.2. Не делайте никакой бизнес-логики в классе Viewmodel, поскольку он просто посредник, а скорее выполняйте вычисления в классе репозитория. 3. Используйте rxjava / rxkotlin в репозитории и возвращайте наблюдаемый объект в Viewmodel из метода репозитория, как только Viewmodel получит уведомление об обновлении представления.

...