Kotlin Flow против LiveData

Во время последнего ввода-вывода Google Хосе Альсеррека и Йигит Бояр сказали нам, что мы больше не должны использовать LiveData для получения данных. Теперь мы должны использовать функции приостановки для одноразовой выборки и использовать поток Kotlin для создания потока данных. Я согласен с тем, что сопрограммы отлично подходят для одноразовой выборки или других операций CRUD, таких как вставка и т. Д. Но в случаях, когда мне нужен поток данных, я не понимаю, какие преимущества дает мне Flow. Мне кажется, что LiveData делает то же самое.

Пример с Flow:

ViewModel

val items = repository.fetchItems().asLiveData()

Репозиторий

fun fetchItems() = itemDao.getItems()

Дао

@Query("SELECT * FROM item")
fun getItems(): Flow<List<Item>>

Пример с LiveData:

ViewModel

val items = repository.fetchItems()

Репозиторий

fun fetchItems() = itemDao.getItems()

Дао

@Query("SELECT * FROM item")
fun getItems(): LiveData<List<Item>>

Я также хотел бы увидеть несколько примеров проектов, использующих сопрограммы и Flow для работы с Room или Retrofit. Я нашел только образец Google ToDo, в котором сопрограммы используются для одноразовой выборки, а затем вручную обновлять данные при изменении.

2 ответа

Решение

Flow это своего рода reactive stream(например, rxjava). Есть множество разных операторов, например.map, buffer()(во всяком случае меньше оператора по сравнению с rxJava). Итак, одно из основных различий междуLiveData а также Flow это то, что ты можешь подписаться на карту computation / transformation в каком-то другом потоке, используя

 flowOn(Dispatcher....). 

Итак, например:-

 flowOf("A","B","C").map { compute(it) }.flowOn(Dispatchers.IO).collect {...} // U can change the execution thread of the computation ( by default its in the same dispatcher as collect )

С участием LiveData а также map, вышеперечисленное не может быть достигнуто напрямую!

Поэтому рекомендуется сохранить поток на уровне репозитория и сделать liveata мостом между пользовательским интерфейсом и репозиторием!

Главное отличие в том, что flow есть несколько операторов, которые livedataнет! Но опять же, вам решать, как вы хотите построить свой проект!

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

У меня нет примера Room, но предположим, что вы визуализируете что-то, что требует времени, но вы хотите отображать результаты при визуализации и буферизации следующих результатов.

private fun render(stuffToPlay: List<Any>): Flow<Sample> = flow {
     val sample = Sample()
     // computationally intensive operation on stuffToPlay
     Thread.sleep(2000)
     emit(sample)
}

Затем в функции "Воспроизведение" вы можете, например, отобразить результаты, где stuffToPlay - это список объектов для рендеринга, например:

playbackJob = GlobalScope.launch(Dispatchers.Default) {

    render(stuffToPlay)
        .buffer(1000)   // tells the Flow how many values should be calculated in advance

        .onCompletion {
            // gets called when all stuff got played
        }
        .collect{sample ->
           // collect the next value in the buffered queue
           // e.g. display sample
        }
}

Важной характеристикой Flow является то, что его код построителя (здесь функция рендеринга) выполняется только тогда, когда он собирается, следовательно, это холодный поток.

Вы также можете обратиться к документации по Asynchronous Flow

Учитывая, что Flow является частью Kotlin, а LiveData - частью библиотеки androidx.lifecycle, я думаю, что Flow используется как часть вариантов использования в чистой архитектуре (без зависимостей от фреймворка).

LiveData, с другой стороны, учитывает жизненный цикл, поэтому соответствует ViewModel.

На данный момент вся моя архитектура использует liveata, но Flow выглядит интересной темой для изучения и принятия.

Другие вопросы по тегам