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

问题描述

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

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

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

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

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

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

解决方法

首先,值得注意的是,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 { }
        }
    }
}