Я создаю приложение для Android с дизайном MVVM, и у меня есть несколько слоев (представление, ViewModel, репозиторий и источник данных, как локальный, так и удаленный). Я хочу, чтобы мой объект репозитория наблюдал за источниками данных, выполнял всю свою логику того, как и при сохранении кеша, отображал данные в правильную форму для вышеуказанного слоя и только затем уведомлял модель представления о новых данных.
Точно так же я хочу, чтобы ViewModel наблюдал за репозиторием на предмет поступления новых данных, затем выполнял всю бизнес-логику и только после этого уведомлял представление.
Моя проблема в том, что LiveData требует объект жизненного цикла, который ViewModel и в репозитории нет.
Я читал об использовании простых наблюдаемых, а не LiveData, но я также читал, что это плохая практика, потому что наблюдаемые будут жить вечно, и это может привести к странным сбоям. Кроме того, у меня есть PageKeyedDataSource, который возвращает только LiveData.
Я также читал об использовании Transformations.map, но что, если я хочу не только отображать данные, но и делать что-то более сложное.
Есть ли способ заставить один слой безопасно наблюдать за другим слоем, не создавая цепочку наблюдаемых LiveData от уровня представления до источника данных?
примечание: моя ViewModel используется в нескольких фрагментах, если это как-то уместно.
1. Прежде всего, если вам нужен контекст в модели представления, используйте AndroidViewModel. 2. Не выполняйте никакой бизнес-логики в классе Viewmodel, так как это просто посредник, а выполняйте вычисления в классе репозитория. 3. Используйте rxjava/rxkotlin в репозитории и верните наблюдаемый объект в Viewmodel из метода репозитория, как только Viewmodel получит уведомление об обновлении.
My problem is that LiveData require lifecycle object
На самом деле, жизненный цикл необязателен. В LiveData есть метод observeForever(Observer), который не требует жизненного цикла. Но это означает, что вы также должны вручную вызвать removeObserver(Observer), когда ваш репозиторий закончит работу, иначе это будет утечка.
На самом деле это не сильно отличается от использования наблюдаемых Rx. В обоих случаях вы должны переопределить onCleared() в своей модели представления и вручную отказаться от подписки (или удалить наблюдателя) из репозитория.
observables are alive forever and this could lead to wierd crashes
Нет, они живы, пока вы их не утилизируете, но вы должны сделать это вручную, поскольку Rx не предоставляет подписку с учетом жизненного цикла.
Is There a way to make one layer safely observe another layer without creating a chain of LiveData observables from the view layer to the DataSource?
Как вы писали, вы пытаетесь создать View-that-observes-ViewModel-that-observes-Repo-that-observes-DataSource. Это уже цепочка, с ней надо разбираться.
Можно безопасно наблюдать за LiveData из ViewModel, потому что View имеет жизненный цикл, а LiveData имеет наблюдение с учетом жизненного цикла.
Но Repo и DataSource не имеют жизненных циклов, поэтому вы должны вручную управлять подписками. Это возможно как с наблюдаемыми LiveData, так и с Rx — вы можете выбрать то, что предпочитаете.
Вы можете использовать DataBinding для отражения данных ViewModel в пользовательском интерфейсе. https://developer.android.com/topic/libraries/привязка данных
Дополнительным преимуществом является то, что вы пишете меньше стандартного кода.