簡體   English   中英

Kotlin 流與 LiveData

[英]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 )。 有許多不同的運算符,例如.mapbuffer() (無論如何,與 rxJava 相比,運算符的數量更少)。 因此, LiveDataFlow之間的主要區別之一是您可以使用其他線程訂閱 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 )

使用LiveDatamap ,以上無法直接實現!

因此建議在存儲庫級別保持流量,並使 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM