为什么状态流多次调用 callectLatest?

Why state flow calls callectLatest multiple times?

所以,我想使用 StateFlow 而不是 LiveData,但我无法弄清楚我的逻辑有什么问题。

我有一个流程,它有一个默认的空值。当我打开一个包含一些数据的对话框时,在我 select 一个数据之后,我将新值发送到流中。

第一次,dialog关闭后调用collectLatest,得到null值(init),emit后得到新值,不错。但是如果我再次打开对话框,并且 select 值,然后关闭对话框,collectLatest 调用了 3 次,然后我再次打开对话框...并且 collectLatest 调用了 4 次,依此类推。

所以这是非常糟糕的行为,我敢肯定,我做错了什么,但我没有看到错误。

在 liveData 中,预期的行为是在对话框关闭后,observer fun 只被调用一次。我想实现这个。

我也检查过,我只发出一次新值,所以没有理由多次触发 collectLatest。

视图模型:

    private val _previousManufacture = MutableStateFlow<PreviousManufactureView?>(null)
    val previousManufacture = _previousManufacture.asStateFlow()

private suspend fun setPreviousManufactureByMachineId(machineId: String) {
        val result = stateReportRepository.getPreviousManufactureByMachineId(machineId)

        if (result is Result.Success) {
            _previousManufacture.emit(result.data)
        } else {
            _previousManufacture.emit(null)
        }
    }

片段:

            lifecycleScope.launchWhenCreated {
                viewModel.previousManufacture.collectLatest {
                    var d = it
                }
            }

[更新] 片段:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        binding.vm = viewModel

        initFlows()
}

 private fun initFlows() {
        lifecycleScope.launchWhenCreated {
            viewModel.openStateOfWorkflowBrowser.collectLatest {
                openStateOfWorkflowSelectionDialog()
            }
        }
...
}

抱歉,我之前在评论中错过了这个,但我认为问题在于您在片段的 lifecycleScope 中调用 launchWhenCreated,而不是在其 viewLifecycle.lifecycleScope 中调用。所以如果 Fragment 被重用(比如在一个对话框片段出现之后),旧的收集器不会被取消并添加一个新的收集器,因为 Fragment 的生命周期还没有结束,只是它之前视图的生命周期。在 Fragment 中使用协程时,几乎应该始终使用 viewLifecycle.lifecycleScope