You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 08:12:50