ui 线程上的片段实例化问题

Problems with fragment instantiation on ui thread

这是一个更普遍的问题,因为我不确定我是否遗漏了什么。

我的设置如下:单个 activity 应用程序,使用导航组件并启动带有 Stepper Layout by Stepstone 的片段。

此步进器包含四个片段,其中一个在 ui 线程上非常重。想象一下,它有 2 个地图视图、大量编辑文本和其他基于位置的内容。

当我启动此步进器片段时,出现明显的延迟,android 停止导航动画并在完成后立即打开步进器。在我看来,这是一个非常糟糕的迹象,因为在较慢的设备上启动时可能会有明显的延迟。

我现在的假设是,这是因为一个重片段而发生的(如果我用其他片段填充步进器,则没有滞后)。我尝试将 onViewCreated 中该片段的所有初始逻辑包装到 viewLifecycleOwner.lifecycleScope.launch{...} 函数中,但无济于事。

总结一下:

遗憾的是我无法指出导致这种延迟的单点代码,但是在实例化片段时有什么方法可以减少ui线程负载,还是 UI 线程的错?

我现在唯一的想法是完全替换这个步进器并根据导航组件构建我自己的步进器,但这只是最后尝试的解决方案,因为它需要 ui最努力了。

如果您以编程方式创建视图并且需要一段时间(因为您需要创建大量视图),您可以考虑在主线程之外执行此操作。完成后,您可以 return 将结果返回到主线程并将其添加到片段中的视图层次结构中。

您可以在 onCreateView() 中进行基本的视图初始化。

override fun onCreateView(): View? {
  // create your basic view first
}

然后在 onViewCreated() 中,您可以开始计算重视图部分(使用协程或任何其他线程机制),例如:

override fun onViewCreated(...) {
  lifecycleScope.launch(Dispatchers.Main) { 
    val complexView: View = heavyViewCreation() // result comes back on the main thread (Dispatchers.Main)
    // add complexView to your existing view hierachy
  }
}

suspend fun heavyViewCreation(): View = withContext(Dispatchers.Default) {
  // create your complex view here, computation is off the main thread (Dispatchers.Default)
}

文档