當前位置:編程學習大全網 - 源碼下載 - Flow 操作符 shareIn 和 stateIn 使用須知

Flow 操作符 shareIn 和 stateIn 使用須知

Flow.shareIn Flow.stateIn 操作符可以將冷流轉換為熱流: 它們可以將來自上遊冷數據流的信息廣播給多個收集者。這兩個操作符通常用於提升性能: 在沒有收集者時加入緩沖;或者幹脆作為壹種緩存機制使用。

本文將會通過示例幫您熟悉 shareIn 與 stateIn 操作符。您將學到如何針對特定用例配置它們,並避免可能遇到的常見陷阱。

繼續使用我 之前文章 中使用過的例子——使用底層數據流生產者發出位置更新。它是壹個使用 callbackFlow 實現的 冷流 。每個新的收集者都會觸發數據流的生產者代碼塊,同時也會將新的回調加入到 FusedLocationProviderClient。

讓我們看看在不同的用例下如何使用 shareIn 與 stateIn 優化 locationsSource 數據流。

我們要討論的第壹個話題是 shareIn 與 stateIn 之間的區別。 shareIn 操作符返回的是 SharedFlow 而 stateIn 返回的是 StateFlow

StateFlow 是 SharedFlow 的壹種特殊配置,旨在優化分享狀態: 最後被發送的項目會重新發送給新的收集者,並且這些項目會使用 Any.equals 進行合並。您可以在 StateFlow 文檔 中查看更多相關信息。

兩者之間的最主要區別,在於 StateFlow 接口允許您通過讀取 value 屬性同步訪問其最後發出的值。而這不是 SharedFlow 的使用方式。

通過***享所有收集者要觀察的同壹數據流實例 (而不是按需創建同壹個數據流的新實例),這些 API 可以為我們提升性能。

在下面的例子中, LocationRepository 消費了 LocationDataSource 暴露的 locationsSource 數據流,同時使用了 shareIn 操作符,從而讓每個對用戶位置信息感興趣的收集者都從同壹數據流實例中收集數據。這裏只創建了壹個 locationsSource 數據流實例並由所有收集者***享:

WhileSubscribed ***享策略用於在沒有收集者時取消上遊數據流。這樣壹來,我們便能在沒有程序對位置更新感興趣時避免資源的浪費。

在下面的例子中,我們的需求有所改變。現在要求我們 保持 監聽位置更新,同時要在應用從後臺返回前臺時在屏幕上顯示最後的 10 個位置:

我們將參數 replay 的值設置為 10,來讓最後發出的 10 個項目保持在內存中,同時在每次有收集者觀察數據流時重新發送這些項目。為了保持內部數據流始終處於活躍狀態並發送位置更新,我們使用了***享策略 SharingStarted.Eagerly ,這樣就算沒有收集者,也能壹直監聽更新。

我們的需求再次發生變化,這次我們不再需要應用處於後臺時 持續 監聽位置更新。不過,我們需要緩存最後發送的項目,讓用戶在獲取當前位置時能在屏幕上看到壹些數據 (即使數據是舊的)。針對這種情況,我們可以使用 stateIn 操作符。

Flow.stateIn 可以緩存最後發送的項目,並重放給新的收集者。

切勿 在調用某個函數調用返回時,使用 shareIn 或 stateIn 創建新的數據流。這樣會在每次函數調用時創建壹個新的 SharedFlow 或 StateFlow,而它們將會壹直保持在內存中,直到作用域被取消或者在沒有任何引用時被垃圾回收。

需要入參 (如 userId ) 的數據流無法簡單地使用 shareIn 或 stateIn ***享。以開源項目——Google I/O 的 Android 應用 iosched 為例,您可以在 源碼中 看到,從 Firestore 獲取用戶事件的數據流是通過 callbackFlow 實現的。由於其接收 userId 作為參數,因此無法簡單使用 shareIn 或 stateIn 操作符對其進行復用。

如何優化這壹用例取決於您應用的需求:

shareIn 與 stateIn 操作符可以與冷流壹同使用來提升性能,您可以使用它們在沒有收集者時添加緩沖,或者直接將其作為緩存機制使用。小心使用它們,不要在每次函數調用時都創建新的數據流實例——這樣會導致資源的浪費及預料之外的問題!

  • 上一篇:如何估算壹頭牛的體重?
  • 下一篇:完成元宵節無視來客任務的方法
  • copyright 2024編程學習大全網