[英]Kotlin Flow vs LiveData
在上一次 Google I/O 中,Jose Alcerreca 和 Yigit Boyar告訴我們,我們不應該再使用 LiveData 來獲取數據。 現在我們應該使用暫停函數進行一次性提取,並使用 Kotlin 的 Flow 創建數據 stream。 我同意協程非常適合一次性獲取或其他 CRUD 操作,例如插入等。但是在我需要數據 stream 的情況下,我不明白 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 示例,其中協程用於一次性獲取,然后在更改時手動重新獲取數據。
Flow
是一種reactive stream
(如 rxjava )。 有許多不同的運算符,例如.map
, buffer()
(無論如何,與 rxJava 相比,運算符的數量更少)。 因此, LiveData
和Flow
之間的主要區別之一是您可以使用其他線程訂閱 map 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
,以上無法直接實現!
因此建議在存儲庫級別保持流量,並使 livedata 成為 UI 和存儲庫之間的橋梁!
主要區別在於
flow
有很多不同的操作符,而livedata
沒有!flow
不具備生命周期感知能力,但liveData
具備生命周期感知能力。 (我們可以將 stateFlow 與repeatOnLifecycle
結合使用以使其具有生命周期意識)但同樣,這取決於你如何構建你的項目!
顧名思義,您可以將 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)
}
然后在您的“播放”function 中,您可以例如顯示其中 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 的一個重要特征是它的構建器代碼(這里是渲染函數)僅在它被收集時才被執行,因此它是一個冷的 stream。
您還可以參考異步流程中的文檔
考慮到 Flow 是 Kotlin 的一部分,而 LiveData 是 androidx.lifecycle 庫的一部分,我認為 Flow 被用作干凈架構中用例的一部分(不依賴於框架)。
另一方面,LiveData 具有生命周期意識,因此與 ViewModel 匹配
目前我的所有架構都使用 livedata,但 Flow 看起來是一個值得研究和采用的有趣話題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.