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

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

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

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

任何帮助都将不胜感激。


当前回答

在我的案例中,错误发生是因为我在启动画面后启用了带有Single Top和Clear Task选项的导航操作。

其他回答

正如在其他回答中提到的,此异常通常发生在用户

同时单击处理导航的多个视图 在处理导航的视图上多次单击。

使用计时器来禁用单击并不是处理此问题的合适方法。如果用户在计时器过期后还没有导航到目的地,应用程序无论如何都会崩溃,在许多情况下,导航不是执行的动作,快速点击是必要的。

在情况1中,android:splitMotionEvents=“false”在xml或setMotionEventSplittingEnabled(false)在源文件应该有帮助。将此属性设置为false将只允许一个视图进行单击。你可以在这里阅读

在情况2中,会有一些东西延迟导航过程,允许用户多次单击视图(API调用,动画等)。如果可能的话,应该解决根本问题,以便即时进行导航,不允许用户两次单击视图。如果延迟是不可避免的,就像在API调用的情况下,禁用视图或使其不可点击将是适当的解决方案。

在我的案例中,错误发生是因为我在启动画面后启用了带有Single Top和Clear Task选项的导航操作。

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

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

为了避免这种崩溃,我的一个同事写了一个小库,它公开了一个SafeNavController,一个围绕NavController的包装器,并处理由于多个导航命令同时发生崩溃的情况。

这里有一篇关于整个问题和解决方案的短文。

你可以在这里找到图书馆。

在调用navigate之前检查currentDestination可能会有帮助。

例如,如果您在导航图fragmentA和fragmentB上有两个片段目的地,并且从fragmentA到fragmentB只有一个动作。当你已经在fragmentB上时,调用navigate(R.id.action_fragmentA_to_fragmentB)将导致IllegalArgumentException。因此,在导航之前,你应该总是检查currentDestination。

if (navController.currentDestination?.id == R.id.fragmentA) {
    navController.navigate(R.id.action_fragmentA_to_fragmentB)
}