本地运行含嵌套导航图的动态功能模块触发Resources$NotFoundException问题
解决本地运行动态导航模块的Resources$NotFoundException问题
这问题我之前也碰到过,核心原因是本地运行时动态模块的资源没有被正确加载——Play商店内部测试时会自动处理动态模块的按需下载和资源合并,但本地直接运行主模块时,动态模块的资源并没有被部署到设备上,导致导航时找不到navigation/two_navigation资源。
下面是几个可行的解决方案,按推荐程度排序:
1. 在Run配置中包含动态模块(最推荐)
Android Studio支持在运行时同时安装主模块和动态模块,只需配置一下:
- 点击顶部运行按钮旁边的下拉菜单,选择「Edit Configurations」
- 在弹出的窗口中,选中你的主模块运行配置
- 切换到「Dynamic Features」标签页
- 勾选你需要的动态模块(这里是
two) - 保存配置后重新运行,Android Studio会同时安装主APK和动态模块APK,资源就能正常访问了
2. 针对Debug构建合并动态模块(快速测试用)
如果不想每次都配置Run选项,可以修改主模块的build.gradle,让Debug构建时自动把动态模块合并到主APK中(仅适合本地测试,Release构建不要这么做):
android { ... buildTypes { debug { bundle { // 强制将指定动态模块合并到主APK dynamicFeatures = [":two"] } } } }
这样Debug构建的APK会包含动态模块的所有资源,导航时就不会找不到资源了。
3. 添加动态模块安装检查逻辑(通用方案)
不管是本地还是线上,都应该在导航前检查动态模块是否已安装,避免崩溃。使用SplitInstallManager实现这个逻辑:
import com.google.android.play.core.splitinstall.SplitInstallManagerFactory import com.google.android.play.core.splitinstall.SplitInstallRequest // 在需要导航的地方添加检查 val splitInstallManager = SplitInstallManagerFactory.create(requireContext()) val targetModule = "two" if (splitInstallManager.installedModules.contains(targetModule)) { // 模块已安装,正常导航 findNavController().navigate(R.id.two_graph) } else { // 启动模块下载 val installRequest = SplitInstallRequest.newBuilder() .addModule(targetModule) .build() splitInstallManager.startInstall(installRequest) .addOnSuccessListener { // 下载完成后再导航 findNavController().navigate(R.id.two_graph) } .addOnFailureListener { e -> // 处理下载失败的情况,比如弹提示 Toast.makeText(requireContext(), "模块下载失败:${e.message}", Toast.LENGTH_SHORT).show() } }
本地运行时,Android Studio会自动处理动态模块的本地安装,不需要真正从Play商店下载,同样能解决崩溃问题。
额外检查项
最后再确认一下导航图的配置是否正确:
- 确保
feature_two_graph中的app:moduleName="two"和动态模块的Gradle模块名完全一致 - 主导航图的
include-dynamic标签中,app:graphPackage(com.xyz.app_name.two)、app:graphResName(two_navigation)和动态模块的导航图信息完全匹配
内容的提问来源于stack exchange,提问作者Nelson.b.austin
相关产品推荐
相关产品推荐

