【问题标题】:After two or more screen rotations, lifecycleScope.launchWhenCreated stops working as expected两次或多次屏幕旋转后,lifecycleScope.launchWhenCreated 按预期停止工作
【发布时间】:2022-01-23 06:53:51
【问题描述】:

我有这样的代码:

    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 被调用,从 flowflowUser /em> 再次将其分配给lateinit user 变量,稍后调用doThingWithUser 一切正常。

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

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

谢谢。

【问题讨论】:

    标签: android kotlin-coroutines android-lifecycle activity-lifecycle fragment-lifecycle


    【解决方案1】:

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

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

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

    【讨论】:

    • 其他问题中提到的重新排序事务对配置更改后通过onCreate() 的订单片段没有影响。
    • 所以它只是随机的?
    • 按照您将片段添加到 FragmentManager 的确切顺序,完全确定。
    • 如果我使用 nav_graph 设置导航会怎样?
    • 导航不会改变添加片段的顺序 - 它们是按照您导航到它们的顺序添加的。
    猜你喜欢
    • 1970-01-01
    • 2020-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    相关资源
    最近更新 更多