该活动结果后,此NavController的导航目标未知

12

我正在使用导航控制器1.0.0alpha05,并且它工作得很好,但是当我在活动结果后执行导航操作时,我遇到了这个可怕的错误。

我有一个单活动/多片段结构,特别是一个具有项目列表的片段和另一个用于添加新项目的表单。

当我添加没有任何图片的项目时,它可以正常返回到上一个带有项目列表的片段,但当我拍照时,导航过程中就会出现异常。

Caused by: java.lang.IllegalArgumentException: navigation destination XX is unknown to this NavController

错误日志

包含该操作的表单片段的导航图:

<fragment
    android:id="@+id/idFormFragment"
    android:name="FormFragment"
    android:label="FormFragment"
    tools:layout="@layout/form_fragment">
    <argument
        android:name="idClient"
        android:defaultValue="-1"
        app:argType="integer" />
    <argument
        android:name="idServer"
        app:argType="string" />
    <action
        android:id="@+id/actionFormToList"
        app:destination="@id/idListFragment" />
</fragment>

使用Safe Args的操作调用代码

FormFragmentDirections.ActionFormToList action = new FormFragmentDirections.ActionFormToList(sample.getIdJob());
Navigation.findNavController(getView()).navigate(action);

谢谢您的时间

4个回答

3
我已经找到了一个非常荒谬的解决方案...
假设您正在使用扩展自NavHostFragment的宿主导航片段,请将此(Kotlin)代码添加到其中:
/*
 * begin DUMB Navigation Component hack
 *
 * This fixes an IllegalArgumentException that can sometimes be thrown from within the
 * Navigation Architecture Component when you try to navigate after the Fragment has had its
 * state restored. It occurs because the navController's currentDestination field is null,
 * which stores where we currently are in the navigation graph. Because it's null, the
 * Navigation Component can't figure out our current position in relation to where we're
 * trying to navigate to, causing the exception to be thrown.
 *
 * This fix gives the navController a little nudge by gently setting it to where we currently
 * are in the navigation graph.
 *
 * This fix is verified as both working AND necessary as of Navigation Components version
 * 1.0.0-alpha07.
 *
 * There's a tiny bit more information at this thread, but it's pretty limited:
 * https://dev59.com/aFQK5IYBdhLWcg3wSeG9
 */
private var checkCurrentDestination = false

override fun onStart() {
    super.onStart()

    if (checkCurrentDestination && navController.currentDestination == null) {
        navController.navigate(navController.graph.startDestination)
    }

    checkCurrentDestination = false
}

override fun onStop() {
    super.onStop()
    checkCurrentDestination = true
}
/*
 * end DUMB Navigation Component hack
 */

在SEO的努力下,堆栈跟踪将如下所示:
Caused by: java.lang.IllegalArgumentException: navigation destination XX is unknown to this NavController

这个问题在后续版本中修复了吗?我在2.0.0版本仍然遇到了这个问题。 - filthy_wizard
我有一个 currentDestination 当我返回时。只是我从一个嵌套在 ViewPager 中的片段中调用 navigate(),所以它没有连接到我的图表。 - filthy_wizard
@filthy_wizard 我不这么认为...我现在正在开发一个项目,使用最新的导航组件,我们不再遇到这个问题了。 - Charles Madere
@CharlesMadere 我正在使用 nav_version_ktx = "2.1.0-alpha06",但仍然遇到了这个问题。你在使用哪个版本? - solaza

2
我发现了一个解决方法,但显然我不能认为它是一种解决方案:
我认为当片段实例状态被恢复时,与该片段关联的nav_graph的操作链接会丢失或其他什么...但我可能错了。
在这种情况下,可以直接使用要导航到的片段的ID,而不是通过安全参数或其ID指向操作本身。
在这种情况下,如果您想传递参数,则必须通过bundle的旧方式进行。
Bundle args = new Bundle();
args.putString(ID_ARG, arg);
Navigation.findNavController(getView()).navigate(R.id.fragmentId, args);

3
我认为这个陈述非常准确:“我认为当片段实例状态被恢复时,与该片段关联的 nav_graph 的操作链接会以某种方式丢失。” 这个问题仍然在[1.0.0-alpha07](https://developer.android.com/jetpack/docs/release-notes)中存在。 - Charles Madere
1
直接使用要导航到的片段的ID存在一些缺点。在片段恢复时,您的返回堆栈将完全中断。但是,它确实解决了抛出无意义异常的直接问题... - Charles Madere
我仍然得到这个荒谬的异常。导航第一次可以工作,然后就崩溃了。哇 - filthy_wizard

1
在我的情况下,出现这种情况是因为我使用了fragmentManager?.popBackStack()来导航回退,而不是像下面正确地导航:
Navigation.findNavController(activity!!, R.id.fragment_container).navigate(
                Navigation.findNavController(activity!!, R.id.fragment_container).graph.startDestination)

0

对于我的情况,我通过替换 - 来解决了这个问题。

 <action
        android:id="@+id/actionFormToList"
        app:destination="@id/idListFragment" />

使用

 <action
            android:id="@+id/actionFormToList"
            app:popUpToInclusive="true" /* If true then also remove the destination from stack while popup */
            app:popUpTo="@id/idFormFragment "  /*The fragment where to land again from destination*/
            app:destination="@id/idListFragment" />

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接