Отображение LiveData в ViewModel из комнаты с сопрограммами

Этот вопрос касается лучших практик программирования для Android с использованием MVVM, LiveData, Room (и, следовательно, RetroFit) и сопрограмм. Одна из лучших практик гласит, что

Длительные операции, такие как вызовы сети или базы данных, должны выполняться асинхронно из потока пользовательского интерфейса.

Текущая документация и блоги подробно объясняют, как это сделать с помощью совместных подпрограмм, и некоторые примеры прекрасно это демонстрируют, например Подсолнечное приложение.

Часть, которую мне не хватает, - это когда ViewModel инициализируется, и ему нужно показать контент из базы данных / репозитория / сети, как выполняется загрузка с использованием совместных подпрограмм. В Sunflower App репозиторий возвращает LiveData, но совместные подпрограммы не используются.

Пример:

В PlantDao мы видим:

@Query("SELECT * FROM plants WHERE id = :plantId")
fun getPlant(plantId: String): LiveData<Plant>

Следовательно, ключевого слова suspend нет, это не часть совместной процедуры.

В plantRepository есть:

fun getPlant(plantId: String) = plantDao.getPlant(plantId)

Снова нет ключевого слова suspend, поэтому нет совместной процедуры.

В PlantDetailViewModel инициализация показывает нам

val plant = plantRepository.getPlant(plantId)

Так что никакой области действия, работы или каких-либо сопутствующих рутинных вещей.

Мои вопросы:

  • Помещение выполняет асинхронный запрос к БД? И если да, то используются ли совместные подпрограммы?
  • Это хорошая практика? Поскольку репо возвращает только LiveData и может использоваться только для возврата LiveData
  • Какие еще стратегии для этого есть? Есть примеры?
  • Будет ли эта стратегия отличаться для сетевых запросов?

person Jens Buysse    schedule 12.11.2019    source источник


Ответы (1)


Помещение выполняет асинхронный запрос к БД? И если да, то используются ли совместные подпрограммы?

Он работает асинхронно и не использует сопрограммы. LiveData учитывает жизненный цикл, поэтому он вызывается только тогда, когда за ним наблюдает возобновленный LifecycleOwner, например фрагмент.

Это хорошая практика? Поскольку репо возвращает только LiveData и может использоваться только для возврата LiveData

Вид. Если вы смотрите https://www.youtube.com/watch?v=zbYYoL7vo9Y и https://www.youtube.com/watch?v=B8ppnjGPAGE, вы можно увидеть, что они избегают использования LiveData в вашем репо или источнике данных и вместо этого используют сопрограммы в этих слоях. Важно понимать, к какой области сопрограммы относится ваш вызов. Ф.и., должен ли он заканчиваться, когда пользователь не видит результата?

Какие еще стратегии для этого есть? Есть примеры? Будет ли эта стратегия отличаться для сетевых запросов?

Новым хитом в Android Town является использование сопрограмм в сочетании с Flow. Если вы используете Retrofit для сетевых вызовов, теперь он поддерживает сопрограммы и. Хорошая лаборатория кода, которую стоит проверить, - это: https://codelabs.developers.google.com/codelabs/kotlin-coroutines/#0

person Michiel    schedule 12.11.2019
comment
Спасибо за ответ! Документация по Room с сопрограммами и LiveData должна быть более ясной, чтобы разработчик знал, что происходит за кулисами. - person Jens Buysse; 12.11.2019