[英]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内部的实际流程发生了什么? onCreate
和onCreateView
方法发生了什么? 还是launchWhenStarted
和launchWhenCreated
在两次旋转后表现不同?
谢谢。
我发现了问题所在。 显然,导航组件与片段生命周期的顺序相混淆,如此处所示。
因此,当屏幕旋转时,由于 backstack 顺序,Navigation 正在创建另一个 Fragment,该 Fragment 也与当前 Fragment 之前的ViewModel的StateFlow交互。 因此,另一个片段onCreate
方法正在向流程发送其他内容,因此弄乱了我当前的片段集合。
解决方案是使流集合独立于片段生命周期,或者更改任一故障片段中的集合。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.