Kotlin Flow与LiveData


10

在上一个Google I / O中,Jose Alcerreca和Yigit Boyar 告诉我们,我们不再应该使用LiveData来获取数据。现在,我们应该将暂停功能用于一次抓取,并使用Kotlin的Flow创建数据流。我同意协程对于单次获取或其他CRUD操作(例如插入等)非常有用。但是,在需要数据流的情况下,我不了解Flow给我带来什么好处。在我看来,LiveData也在这样做。

流示例:

视图模型

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

资料库

fun fetchItems() = itemDao.getItems()

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

LiveData示例:

视图模型

val items = repository.fetchItems()

资料库

fun fetchItems() = itemDao.getItems()

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

我还希望看到一些使用协程和Flow与Room或Retrofit协同工作的项目示例。我只找到了一个Google的ToDo示例,其中协程用于一次获取,然后在更改时手动重新获取数据。

Answers:


3

Flow有点reactive stream像(如rxjava)。有很多不同的运算符,例如.mapbuffer()(与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 )

使用LiveDatamap不能直接实现以上目的!

因此,建议保持流在存储库级别,并使livedata成为UI和存储库之间的桥梁!

主要的区别是flow有很多没有的运算符livedata!但同样,取决于您,您要如何构建您的项目!


3

顾名思义,您可以将Flow视为多个异步计算值的连续流。从我的角度来看,LiveData与Flow之间的主要区别在于,Flow连续发出结果,而LiveData将在获取所有数据时更新并立即返回所有值。在您的示例中,您正在获取单个值,这在我看来并不完全是针对Flow的。

我没有“房间”示例,但假设您正在渲染需要时间的内容,但是您想在渲染和缓冲下一个结果时显示结果。

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的一个重要特征是它的生成器代码(此处为render函数)仅在被收集时才执行,因此很冷

您也可以参考异步流程中的文档

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.