6

所以我最近迁移到导航组件(2.2.0-alpha01)。当我在高端设备上工作时,我并没有真正注意到任何减速,但是当我完成后,测试人员开始报告应用程序导航缓慢。

在我的导航代码中,我使用findNavController().navigate(CustomFragmentDirections.actionEtc())findNavController().popBackStack(fragmentId, false) 之类的调用,我还使用带导航的 safeargs。在我的导航 xml 中,我的操作严重依赖popUpToapp:launchSingleTop="true"

为了调查,我在 BaseFragment 类中制作了非常基本的分析器:

 private var lastTimestamp = System.currentTimeMillis()

protected fun getEllapsedTime(): String {
    val currTime = System.currentTimeMillis()
    val elapsedTime = currTime - lastTimestamp
    lastTimestamp = currTime
    return "${elapsedTime}ms"
}

override fun onAttach(context: Context) {
    Timber.d("onAttach(${javaClass.simpleName})(${getEllapsedTime()})")
    super.onAttach(context)
}

override fun onCreate(savedInstanceState: Bundle?) {
    Timber.d("onCreate(${javaClass.simpleName})(${getEllapsedTime()})")
    super.onCreate(savedInstanceState)
    savedInstanceState?.let { restoreState(it) }
}

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    Timber.d("onCreateView(${javaClass.simpleName})(${getEllapsedTime()})")
    return inflater.inflate(layoutRes, container, false)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    Timber.d("onViewCreated(${javaClass.simpleName})(${getEllapsedTime()})")
    super.onViewCreated(view, savedInstanceState)
}

override fun onActivityCreated(savedInstanceState: Bundle?) {
    Timber.d("onActivityCreated(${javaClass.simpleName})(${getEllapsedTime()})")
    super.onActivityCreated(savedInstanceState)
}

override fun onStart() {
    Timber.d("onStart(${javaClass.simpleName})(${getEllapsedTime()})")
    super.onStart()
}

override fun onResume() {
    Timber.d("onResume(${javaClass.simpleName})(${getEllapsedTime()})")
    super.onResume()
    requireActivity().window?.decorView?.post {
        firstFrameRendered()
    }
}

private fun firstFrameRendered() {
    Timber.d("onFrameRendered(${javaClass.simpleName})(${getEllapsedTime()})")
}

override fun onPause() {
    Timber.d("onPause(${javaClass.simpleName})(${getEllapsedTime()})")
    super.onPause()
}

override fun onStop() {
    Timber.d("onStop(${javaClass.simpleName})(${getEllapsedTime()})")
    super.onStop()
}

override fun onDestroyView() {
    Timber.d("onDestroyView(${javaClass.simpleName})(${getEllapsedTime()})")
    super.onDestroyView()
}

override fun onDestroy() {
    Timber.d("onDestroy(${javaClass.simpleName})(${getEllapsedTime()})")
    super.onDestroy()
}

override fun onDetach() {
    Timber.d("onDetach(${javaClass.simpleName})(${getEllapsedTime()})")
    super.onDetach()
}

我尝试使用 android studio profiler 进行分析,但并没有真正注意到任何异常。我也尝试了window.addOnFrameMetricsAvailableListener但它几乎给了我与我的探查器代码相同的结果。重要性的主要方法是onFrameRendered。基本思想是让布局膨胀和渲染,并在屏幕渲染后立即计算自调用 onResume 以来经过的毫秒数。

我尝试了不同的设备并且时间不是很一致,但是在多次测量相同的转换之后,我注意到一些趋势,与以前使用简单 supportFragmentManager 事务的应用程序导航相比,我所有的布局现在需要几乎两倍的时间来加载。

我尝试将导航从一个片段隔离到另一个片段,但我总是会得到这种糟糕的性能。

目前我知道这与导航切换片段的方式有关,因为如果我用我直接使用 FragmentManager 的自定义代码模拟 NavController,我会获得与旧代码相同的良好性能。如果我能找到确切的问题,将更新问题。

同时,有没有人知道可能出了什么问题?

4

0 回答 0