AndroidX Navigation 2.7.5中如何强制调用NavController#onGraphCreated?
问题分析
在AndroidX Navigation 2.7.5版本中,当Activity设置为singleTop启动模式时,首次启动在onCreate调用setGraph可正常触发NavController#onGraphCreated;但再次通过onNewIntent调用setGraph时,该方法不再触发,导致UI无法更新。此问题源于Navigation组件的一次逻辑变更:当现有导航图与新设置的导航图ID相同时,会跳过onGraphCreated的调用流程。
解决方案
以下是几种可行的解决方法,按推荐优先级排序:
1. 先清空导航图再重新设置
通过先将导航图设为null,强制NavController触发重新创建流程,再设置目标导航图:
override fun onNewIntent(intent: Intent?) { super.onNewIntent(intent) val navController = findNavController(R.id.nav_host_fragment) // 清空现有导航图 navController.setGraph(null) // 重新设置目标导航图 navController.setGraph(R.navigation.your_nav_graph) }
此方法利用NavController内部逻辑:设置null后,后续设置新图会被判定为首次创建,从而触发onGraphCreated。
2. 反射调用onGraphCreated(应急方案)
若上述方法不适用,可通过反射直接调用onGraphCreated,但需注意这依赖内部API,后续版本可能失效:
override fun onNewIntent(intent: Intent?) { super.onNewIntent(intent) val navController = findNavController(R.id.nav_host_fragment) val navInflater = navController.navInflater val newGraph = navInflater.inflate(R.navigation.your_nav_graph) try { val method = NavController::class.java.getDeclaredMethod( "onGraphCreated", NavGraph::class.java ) method.isAccessible = true method.invoke(navController, newGraph) } catch (e: Exception) { e.printStackTrace() } }
3. 替换为参数传递更新UI(推荐长期方案)
如果仅需更新UI而非完全替换导航图,建议通过navigate传递参数,在目标Fragment中接收并更新:
// 在onNewIntent中传递参数 override fun onNewIntent(intent: Intent?) { super.onNewIntent(intent) val navController = findNavController(R.id.nav_host_fragment) val updateArgs = Bundle().apply { putString("update_key", intent?.getStringExtra("your_extra_key")) } // 导航到目标页面并传递参数 navController.navigate(R.id.target_fragment, updateArgs) } // 在目标Fragment中处理更新 override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) // 接收初始参数 arguments?.getString("update_key")?.let { updateUi(it) } // 监听参数变化(使用Safe Args更安全) setFragmentResultListener("update_request") { _, bundle -> val newValue = bundle.getString("update_key") newValue?.let { updateUi(it) } } }
4. 临时降级到2.7.4版本
若上述方案均无法快速适配,可临时将Navigation组件版本降级到2.7.4,恢复原有逻辑:
dependencies { implementation "androidx.navigation:navigation-fragment-ktx:2.7.4" implementation "androidx.navigation:navigation-ui-ktx:2.7.4" }
内容的提问来源于stack exchange,提问作者kwmt
相关产品推荐
相关产品推荐

