我有一个问题,我一个人走不动. 在我的view Model中,有两个合并为一个流的StateFlow. 就像val mergedState = merge(state1, state2)个. 现在,当我更新state1时,mergedState的值也更改为state1的值. 但是,当我try 更新state2时,mergedState的值不会改变.

为了更好地演示,我编写了一个简单的示例:

这是一个视图模型

class FlowViewModel : ViewModel() {

    private val state1 = MutableStateFlow(0)
    private val state2 = MutableStateFlow(0)

    val mergedState = merge(state1, state2)

    fun updateState1(value: Int) {
        state1.value = value
    }

    fun updateState2(value: Int) {
        state2.value = value
    }
}

下面是测试它的代码

class ExampleUnitTest {

    private lateinit var flowViewModel: FlowViewModel

    @Before
    fun setUp() {
        Dispatchers.setMain(UnconfinedTestDispatcher())
        flowViewModel = FlowViewModel()
    }

    @After
    fun tearDown() {
        Dispatchers.resetMain()
    }

    @Test
    fun `test merged flow`() = runTest {
        assertThat(flowViewModel.mergedState.first()).isEqualTo(0)

        flowViewModel.updateState1(1)
        assertThat(flowViewModel.mergedState.first()).isEqualTo(1) //works as expected

        flowViewModel.updateState2(2)
        assertThat(flowViewModel.mergedState.first()).isEqualTo(2) //the value is still 1
    }
}

我也不管我先更新哪个州. 看起来只有更新了state1才会更新mergedState.

我很确定我在这里忽略了一些东西.

推荐答案

记住,流动是冷的,它们不会保持状态.

当你开始收集它时,你的merge(state1, state2)总是会发出电流state1,然后是state2,只有在那之后它才会开始"转发"更新.

您的断言:

assertThat(flowViewModel.mergedState.first()).isEqualTo(1)

在第一个值之后开始并完成合并状态的收集,该值将始终为当前状态state1.

你可以 Select :让你的mergedState个州流动起来:

val mergedState = merge(state1, state2).stateIn(viewModelScope, SharingStarted.Eagerly, state1.value)

或者更新您的测试以继续收集mergedState,而不是重新启动3次.

Kotlin相关问答推荐

Kotlin 函数名后面的大括号是什么意思?

Kotlin 中命名构造函数的惯用方式

Kotlin中用于调用常量名称的枚举类方法之间的区别

kotlin 父类具有依赖于抽象变量的变量

如何在 kotlin 中使用带有泛型的密封类

Kotlin 插件之间的区别

kotlin 单例异常是好是坏?

Kotlin RxJava 可空的错误

基类中的 ViewModelProviders.get(...)

在 kotlin 中写入 parcer 可空值

在粘贴时将 java 转换为 kotlin

包括登录Elvis operator?

如何在主线程上使用 Kotlin 协程 await()

如何使用 Kotlin Coroutines 使 setOnClickListener debounce 1 秒?

Kotlin惰性默认属性

Kotlin:子构造函数如何使用其父构造函数的辅助构造函数?

将字符串编码为Kotlin中的UTF-8

Android Studio - java.io.IOException:无法生成 v1 签名

具有多个 parameter的 Kotlin 枚举

Dagger 2 androidx fragment不兼容类型