所以我最近迁移到了导航组件( 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,则可以获得与旧代码相同的良好性能。如果我能找到确切的问题,将会更新该问题。
与此同时,是否有人知道什么地方可能出问题了?