2

我创建了一个从中发出数据的流。当我两次收集此流时,从同一个变量发出了 2 组不同的数据,而不是向两个收集器发出相同的值。

我有一个我自己创建的简单流程。文本将每秒记录两次

    val demoFlow: Flow<String> = flow {
        while (true) {
            val text = "Flow ${(0..100).random()}"
            Log.d("TAG", text)
            emit(text)
            delay(1000)
        }
    }

在我的 viewModel 中,我有一个简单的函数可以获取上一个 Flow

fun getSimpleFlow() = FlowRepository.demoFlow

在我的 Fragment 中,我收集并显示我的 Flow

        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                launch {
                    viewModel.getSimpleFlow().collect {
                        binding.tv1.text = it
                    }
                }
                launch {
                    viewModel.getSimpleFlow().collect {
                        binding.tv2.text = it
                    }
                }
            }
        }

如果我将 Flow 转换为 StateFlow 或 SharedFlow,我不再有这个问题。我不明白为什么会发生这种情况,因为我使用的是相同的“demoFlow”变量。有没有办法在不转换为 StateFlow 或 SharedFlow 的情况下从“demoFlow”获取相同的值?

4

1 回答 1

3

常规Flows 很冷,这种行为是设计使然。

是相同的demoFlow,所以你有相同的Flow实例。但是,多次收集流实际上flow { ... }每次从一开始就运行定义内的主体。每个独立的集合都有自己的变量i等。

使用 aStateFlow或 aSharedFlow允许在多个收集器之间共享流源。如果您在某个源流上使用shareInstateIn,则该源流只收集一次,并且从此源流收集的项目被共享并发送到结果状态/共享流的每个收集器。这就是为什么它的行为不同。

简而言之,重用Flow实例不足以共享集合。您需要使用专门为此设计的流类型。

于 2022-02-10T14:41:12.367 回答