Home API 的 Kotlin 版本會使用流程,這是 Kotlin 語言的功能,可提供強大的功能來處理非同步資料串流,包括轉換、篩選、對應、轉換至和從集合轉換等。
協同程式與流程密切相關,可提供編寫非同步程式碼的優雅抽象,讓開發人員不必明確編寫回呼例程。流程與協同程式密切配合,可用於非同步方式從協同程式擷取資料,無須等待函式或執行緒完成。
消費者會在「收集」程序中,從資料流中擷取資料。Kotlin 流程有 collect()
函式,可用於此用途。收集期間流程中的情況取決於流程類型。
Kotlin 資料流 (Flow<T>
) 預設為冷,也就是說,只有在呼叫 collect()
時,資料流建構工具程式碼才會產生資料。相反地,熱流程會立即產生資料,並將資料緩衝在記憶體中,就像佇列一樣,以便在資料使用時讀取。由於熱流會在記憶體中維護資料,因此被視為有狀態。
您可以使用 shareIn
運算子將資料流從冷轉熱 (請參閱「使用 shareIn
將冷資料流轉為熱資料流」)。您也可以使用 SharedFlow
或 StateFlow
將冷資料流轉為熱資料流。
範例應用程式如何使用流程
範例應用程式使用 Jetpack Compose 中的 View 模型,並連結至 Home API 中的流程。許多應用程式範例的 UI 元素都是由狀態驅動,但可以與使用者互動。這個範例應用程式也會在 UI 中將裝置狀態與「樂觀」狀態混合,提供即時的使用者體驗。「樂觀」一詞的意思是應用程式會假設特定動作成功,並立即更新 UI 以反映預期結果,而不會等待確認。如果發現動作失敗,UI 會更新,以反映實際狀態。
在範例應用程式中,系統會為檢視區塊模型的每個層級 (結構、房間、裝置) 建立流程。舉例來說,這會對 GlobalViewModel.kt
中具有下列呼叫的結構體執行此操作:
fun getStructuresState(): StateFlow<List<StructureModel>?> =
homeClient
.structures()
.map { structures -> structures.map { StructureModel(it.name, it) }.sortedBy { it.name } }
.handleErrors()
.flowOn(Dispatchers.IO)
.stateIn(scope = viewModelScope, started = SharingStarted.WhileSubscribed(), null)
emitAll()
會收集指定資料流中的所有值,並將這些值傳送至收集器。stateIn()
會將上游流程中單一執行中例項的最新發出值,與多個下游訂閱者共用。詳情請參閱 kotlinx.coroutines.flow
參考資料。
Jetpack Compose
如要在本機記憶體中儲存流程物件,並防止其終止,請使用 Kotlin remember
API。
在 Jetpack Compose 中,如果您將此功能與 collectAsStateWithLifecycle()
搭配使用,Jetpack 會根據應用程式 UI 顯示該狀態是否實際處於前景,自動管理訂閱和取消訂閱流程。
範例應用程式中的簡單呼叫就能做到這點。使用先前顯示的 getStructuresState()
函式:
val structuresList by
remember(globalViewModel) { globalViewModel.getStructuresState() }.collectAsStateWithLifecycle()
從現在開始,當結構的任何狀態 (例如 name
) 發生變更時,使用該狀態的可組合函式會自動反映更新後的狀態。在範例應用程式中,這個函式為 HomeActivityContent()
。
資源
如要進一步瞭解 Kotlin、資料流、協同程式和 Jetpack Compose,請參閱下列資源:
- 使用 Kotlin 開發 Android 應用程式
- 瞭解 Android 適用的 Kotlin
- Android 上的 Kotlin 協同程式。以下程式碼研究室可能會派上用場:
- Android 上的 Kotlin 資料流,具體來說是 StateFlow。
- 狀態和 Jetpack Compose,特別是
collectAsStateWithLifecycle()
函式。這個函式會根據 UI 顯示該狀態是否實際處於前景,自動管理訂閱和取消訂閱流程。 - 如果您要使用 Automation API,請參閱 Kotlin 型別安全建構工具,瞭解 Automation DSL 的運作方式。