? ? ? ?這一節了解一下Compose中的事件總線,在Jetpack Compose里,官方沒有直接提供事件總線,但可以借助第三方庫或者自定義實現來達成事件總線的功能,進而在不同的 Compose 控件間同步數據。
自定義事件總線
import androidx.compose.runtime.*
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import java.util.*object EventBus {private val listeners = mutableListOf<(Any) -> Unit>()fun register(listener: (Any) -> Unit) {listeners.add(listener)}fun unregister(listener: (Any) -> Unit) {listeners.remove(listener)}fun post(event: Any) {listeners.forEach { it(event) }}
}@Composable
fun SenderComponent() {Button(onClick = {EventBus.post("New data from sender")}) {Text(text = "Send Data")}
}@Composable
fun ReceiverComponent() {var receivedData by remember { mutableStateOf("No data received") }DisposableEffect(Unit) {val listener: (Any) -> Unit = { event ->if (event is String) {receivedData = event}}EventBus.register(listener)onDispose {EventBus.unregister(listener)}}Text(text = receivedData)
}@Composable
fun EventBusExample() {SenderComponent()ReceiverComponent()
}
分析:EventBus 對象管理事件的注冊、注銷和發布。register 方法用于添加監聽器,unregister 方法用于移除監聽器,post 方法用于發布事件。
優點
簡單易實現:自定義事件總線的實現方式比較基礎,不需要引入額外的依賴庫。可以根據自己的需求,用簡單的集合和回調機制來實現一個基本的事件總線,對于小型項目或者簡單的通信需求來說,實現成本較低。
靈活性高:可以完全按照自己的需求來設計事件總線的接口和功能。例如,你可以自定義事件的優先級、過濾規則等,滿足一些特殊的業務需求。
缺點
缺乏響應式編程特性:自定義事件總線通常是基于回調機制實現的,不具備 Kotlin Flow 那樣的響應式編程能力。在處理異步數據流、背壓等復雜場景時,需要自己手動實現很多邏輯,增加了開發的復雜度。
使用 Kotlin Flow 實現事件總線
import androidx.compose.runtime.*
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlowobject FlowEventBus {private val eventFlow = MutableSharedFlow<Any>()val events: SharedFlow<Any> = eventFlowsuspend fun post(event: Any) {eventFlow.emit(event)}
}@Composable
fun FlowSenderComponent() {val scope = rememberCoroutineScope()Button(onClick = {scope.launch {FlowEventBus.post("New data from flow sender")}}) {Text(text = "Send Data with Flow")}
}@Composable
fun FlowReceiverComponent() {var receivedData by remember { mutableStateOf("No data received") }val scope = rememberCoroutineScope()LaunchedEffect(Unit) {FlowEventBus.events.collect { event ->if (event is String) {receivedData = event}}}Text(text = receivedData)
}@Composable
fun FlowEventBusExample() {FlowSenderComponent()FlowReceiverComponent()
}
優點
響應式編程:Kotlin Flow 是 Kotlin 協程中的響應式編程庫,具有強大的異步數據流處理能力。使用 Kotlin Flow 實現事件總線可以方便地處理異步事件、背壓、過濾、轉換等操作,使代碼更加簡潔和易于維護。
類型安全:Kotlin Flow 是類型安全的,編譯器可以在編譯時檢查類型錯誤,減少運行時錯誤的發生。這使得代碼更加健壯,易于調試和維護。
與協程集成:Kotlin Flow 與 Kotlin 協程緊密集成,可以方便地在協程中使用。在處理異步事件時,可以充分利用協程的特性,如掛起、恢復等,提高代碼的性能和可讀性。
缺點
學習成本高:Kotlin Flow 是一個相對復雜的庫,需要一定的時間來學習和掌握其使用方法。對于初學者來說,可能會覺得難以理解和使用。
引入額外依賴:如果項目中原本沒有使用 Kotlin Flow,引入它會增加項目的依賴和代碼量。
? ? ? ?簡而言之,若項目規模較小、通信需求簡單,更適合使用自定義事件總線。若項目需要處理復雜的異步數據流、對代碼的可維護性和可擴展性要求較高,那么使用 Kotlin Flow 實現事件總線是更好的選擇。