繁体   English   中英

两次或多次屏幕旋转后,lifecycleScope.launchWhenCreated 按预期停止工作

[英]After two or more screen rotations, lifecycleScope.launchWhenCreated stops working as expected

我有这样的代码:

    private val appViewModel: AppViewModel by activityViewModels()
    private lateinit var user: User

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // This sets the variable user to the value collected from a StateFlow from appViewmodel 
        lifecycleScope.launchWhenCreated {
            appViewModel.user.collect { flowUser -> user = flowUser }
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        
        // This method utilizes the lateinit user variable
        lifecycleScope.launchWhenStarted {
            doThingWithUser()
        }

        return binding?.root
    }

由于StateFlow的值即使在被收集后仍然存在,在屏幕旋转后,第一个lifecycleScope.launchWhenCreated Scope.launchWhenCreated 被调用,再次从中收集flowUser ,将其分配给 lateinit user变量,稍后再调用doThingWithUser ,一切正常。

但是经过两次或多次旋转后,情况就不再如此了,由于某种原因, user没有被初始化, doThingWithUser被调用并且应用程序因kotlin.UninitializedPropertyAccessException而崩溃。

我究竟做错了什么? 两次收集/屏幕旋转后, StateFlow的值是否消失? ViewModel内部的实际流程发生了什么? onCreateonCreateView方法发生了什么? 还是launchWhenStartedlaunchWhenCreated在两次旋转后表现不同?

谢谢。

我发现了问题所在。 显然,导航组件与片段生命周期的顺序相混淆,如此处所示

因此,当屏幕旋转时,由于 backstack 顺序,Navigation 正在创建另一个 Fragment,该 Fragment 也与当前 Fragment 之前的ViewModelStateFlow交互。 因此,另一个片段onCreate方法正在向流程发送其他内容,因此弄乱了我当前的片段集合。

解决方案是使流集合独立于片段生命周期,或者更改任一故障片段中的集合。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM