Material3 1.2.1与asFlow()兼容问题及解决方案咨询
问题描述
我修改了Skizo-ozᴉʞS ツ的变体代码后,以下代码可以正常运行:
private val eventsChannel = MutableSharedFlow<Event>( replay = 1, extraBufferCapacity = 64, onBufferOverflow = BufferOverflow.DROP_OLDEST )
以及对应的sendEvent函数:
fun sendEvent(event: Event) { eventBusScope.launch { eventsChannel.emit(event) } }
但当我将Material3从1.1.2升级到1.2.1后,原有EventBus代码中使用asFlow()时出现编译错误,错误提示如下:
Using 'asFlow(): Flow
' is an error. 'BroadcastChannel' is obsolete and all corresponding operators are deprecated in the favour of StateFlow and SharedFlow
原有EventBus代码如下:
object EventBus { @OptIn(ObsoleteCoroutinesApi::class) private val eventsChannel = ConflatedBroadcastChannel<Event>() private val screenState = MutableStateFlow(ContentType.EMPTY) private val screenOperatorState = MutableStateFlow(OperatorContentType.EMPTY) @OptIn(ObsoleteCoroutinesApi::class) val eventFlow: Flow<Event> get() = eventsChannel.asFlow() val getScreen: Flow<ContentType> get() = screenState val getOperatorScreen: Flow<OperatorContentType> get() = screenOperatorState @OptIn(ObsoleteCoroutinesApi::class) fun sendEvent(event: Event) { Log.d("MyLogBackArrow","sendEvent in EventBus $event") eventsChannel.trySend(event).isSuccess } fun <C>setScreen(screenType: C) { when(screenType){ is ContentType -> { screenState.value = screenType } is OperatorContentType -> { screenOperatorState.value = screenType } } }
请问是否可以同时使用Material3 1.2.1和asFlow()?
解决方案
不行,无法同时使用Material3 1.2.1和基于BroadcastChannel的asFlow()。原因是Material3 1.2.1依赖的Coroutines版本已将BroadcastChannel相关API标记为错误级别的废弃(不再只是警告),强制要求迁移到StateFlow或SharedFlow。
你需要把原有基于ConflatedBroadcastChannel的实现完全替换为MutableSharedFlow,这和你之前修改的变体代码逻辑一致,且能完全替代原有功能:
ConflatedBroadcastChannel的行为等价于replay = 1、onBufferOverflow = BufferOverflow.DROP_OLDEST的MutableSharedFlow- 替换后可以移除所有
@OptIn(ObsoleteCoroutinesApi::class)注解
修改后的完整EventBus代码如下:
object EventBus { // 替代ConflatedBroadcastChannel,行为完全一致 private val eventsChannel = MutableSharedFlow<Event>( replay = 1, extraBufferCapacity = 0, // ConflatedBroadcastChannel本身无额外缓冲区,设为0即可 onBufferOverflow = BufferOverflow.DROP_OLDEST ) private val screenState = MutableStateFlow(ContentType.EMPTY) private val screenOperatorState = MutableStateFlow(OperatorContentType.EMPTY) val eventFlow: Flow<Event> get() = eventsChannel val getScreen: Flow<ContentType> get() = screenState val getOperatorScreen: Flow<OperatorContentType> get() = screenOperatorState fun sendEvent(event: Event) { Log.d("MyLogBackArrow","sendEvent in EventBus $event") // 用tryEmit替代trySend,无需协程作用域 eventsChannel.tryEmit(event) } fun <C>setScreen(screenType: C) { when(screenType){ is ContentType -> { screenState.value = screenType } is OperatorContentType -> { screenOperatorState.value = screenType } } } }
注意事项:
- 若需处理发送失败场景,可检查
tryEmit的返回值(Boolean类型,成功返回true) - 若之前需要保留额外缓冲区,可根据实际需求调整
MutableSharedFlow的extraBufferCapacity参数
内容的提问来源于stack exchange,提问作者alex
相关产品推荐
相关产品推荐

