当我试图从一个片段导航到另一个片段时,我遇到了新的Android导航架构组件的问题,我得到了这个奇怪的错误:

java.lang.IllegalArgumentException: navigation destination XXX
is unknown to this NavController

其他导航都很好,除了这个。

我使用Fragment的findNavController()函数来访问NavController。

任何帮助都将不胜感激。


当前回答

发生此错误可能是因为您将目标屏幕分配给了错误的图形

其他回答

似乎混合fragmentManager控件的backstack和Navigation Architecture控件的backstack也会导致这个问题。

例如,最初的CameraX基本示例使用fragmentManager后台导航,如下所示,它似乎没有正确地与导航交互:

// Handle back button press
        view.findViewById<ImageButton>(R.id.back_button).setOnClickListener {
            fragmentManager?.popBackStack()
        }

如果你在从主片段(在本例中是相机片段)移动之前记录这个版本的“当前目的地”,然后当你返回主片段时再次记录它,你可以从日志中的id中看到id是不相同的。据猜测,导航在移动到片段时更新了它,而fragmntManager在移动回来时没有再次更新它。日志显示:

修改前:D/CameraXBasic: currentDest?: androidx.navigation.fragment.FragmentNavigator Destination@b713195美元 After: D/CameraXBasic: currentDest?: androidx.navigation.fragment.FragmentNavigator Destination@9807d8f美元

更新版的CameraX基本示例使用导航返回如下:

 // Handle back button press
        view.findViewById<ImageButton>(R.id.back_button).setOnClickListener {
            Navigation.findNavController(requireActivity(), R.id.fragment_container).navigateUp()
        }

这可以正常工作,当返回到主片段时,日志显示相同的id。

修改前:D/CameraXBasic: currentDest?: androidx.navigation.fragment.FragmentNavigator Destination@b713195美元 After: D/CameraXBasic: currentDest?: androidx.navigation.fragment.FragmentNavigator Destination@b713195美元

我怀疑这个故事的寓意,至少在这个时候,是要非常小心地混合导航和fragmentManager导航。

在我的例子中,我使用了一个自定义的后退按钮来向上导航。我调用了onBackPressed()而不是下面的代码

findNavController(R.id.navigation_host_fragment).navigateUp()

这导致发生IllegalArgumentException。在我将其更改为使用navigateUp()方法之后,我就不会再次崩溃了。

看来你在完成任务。应用程序可能有一次性设置或一系列登录屏幕。这些有条件的屏幕不应该被认为是应用程序的起始目的地。

https://developer.android.com/topic/libraries/architecture/navigation/navigation-conditional

I am calling the 2.3.1 Navigation and the same error occurs when the application configuration changes. When the cause of the problem was found through Debug, the GaphId in NavHostFragment did not take effect as the ID currently set by calling navController.setGraph(). The GraphId of NavHostFragment can only be obtained from the <androidx.fragment.app.FragmentContainerView/> tag. At this time, this problem will occur if there are multiple GraphIds dynamically set in your code. When the interface is restored, the Destination cannot be found in the cached GraphId. You can solve this problem by manually specifying the value of mGraphId in NavHostFragment through reflection when switching Graph.

navController.setGraph(R.navigation.home_book_navigation);
try {
    Field graphIdField = hostFragment.getClass().getDeclaredField("mGraphId");
    graphIdField.setAccessible(true);
    graphIdField.set(navHostFragment, R.navigation.home_book_navigation);
} catch (NoSuchFieldException | IllegalAccessException e) {
    e.printStackTrace();
}

答案在链接:https://stackoverflow.com/a/67614469/5151336

为导航器增加了安全导航的扩展功能。