You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 09:38:17