片段和视图生命周期所有者偏差

时间:2020-10-27 06:52:29

标签: android kotlin android-fragments kotlin-coroutines kotlin-flow

我正在viewLifecycleOwner上收集流。它在Dispatchers.Default上流动,但是集合本身在Dispatchers.Main上发生。

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    viewLifecycleOwner.lifecycleScope.launch {
        flow.flowOn(Default).collect {
            requireContext()
        }
    }
}

在一个场合中,我发现IllegalStateException声明该片段未附加。

IllegalStateException:片段测试未附加到上下文。

我假设在拆离片段之前将取消对流的收集。

协程如何在分离的碎片上恢复?

1 个答案:

答案 0 :(得分:1)

首先,值得注意的是,flowOn会更改上游上下文,以防您拥有mapfilter etc 之类的运算符功能,位于flowOn之前。因此,它不会影响collect之类的终端功能的上下文。它在Failed quitting the previous firebase emulator上有说明。因此,如果要更改collect终端的上下文,则应从外部块进行更改,即launch构建器函数。

接下来,为避免IllegalStateException安全使用context,而不是requireContext(),以确保该片段已附加。毫无疑问,在破坏该片段时,应该终止在viewLifecycleOwner.lifecycleScope中启动的所有协程,但是在某些情况下,线程中可能存在竞争条件,从而导致此问题。

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

    viewLifecycleOwner.lifecycleScope.launch(Main/Default/WhateverContextYouWant) {
        flow.collect {
            context?.let { }
        }
    }
}