所以我最近迁移到导航组件(2.2.0-alpha01)。当我在高端设备上工作时,我并没有真正注意到任何减速,但是当我完成后,测试人员开始报告应用程序导航缓慢。
在我的导航代码中,我使用findNavController().navigate(CustomFragmentDirections.actionEtc())或findNavController().popBackStack(fragmentId, false) 之类的调用,我还使用带导航的 safeargs。在我的导航 xml 中,我的操作严重依赖popUpTo和app: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,我会获得与旧代码相同的良好性能。如果我能找到确切的问题,将更新问题。
同时,有没有人知道可能出了什么问题?