【问题标题】:Navigation destination unknown to this NavController after an activity result活动结果后此 NavController 未知的导航目的地
【发布时间】:2020-11-11 02:37:40
【问题描述】:

我正在使用导航控制器 1.0.0alpha05,它运行良好,但是当我在活动结果后执行导航操作时,我正在努力解决这个可怕的错误。

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

当我添加另一个没有任何图片的照片时,它正在工作并返回到带有项目列表的前一个,但是当我拍摄一些照片时,我在导航过程中出现异常。

原因:java.lang.IllegalArgumentException:此 NavController 未知导航目的地 XX

Error log

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

<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>

带有安全参数的动作调用代码

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

感谢您的宝贵时间

【问题讨论】:

    标签: android android-architecture-components android-jetpack android-architecture-navigation


    【解决方案1】:

    好吧,我已经设法找到了一个荒谬的解决方案......

    假设您正在使用从 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://stackoverflow.com/questions/52101617/navigation-destination-unknown-to-this-navcontroller-after-an-activity-result
     */
    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 上仍然遇到这个问题
    • 当我返回时,我有一个 currentDestination。它只是从视图页面中的嵌套片段调用导航()。所以它没有附加到我的图表上。
    • @filthy_wizard 我不这么认为......我现在正在做一个使用最新导航组件的项目,我们不再遇到这个问题了。
    • @CharlesMadere 我正在使用nav_version_ktx = "2.1.0-alpha06",但仍然有这个问题。你用的是哪个版本?
    【解决方案2】:

    我找到了解决方法,但显然我不能将其视为解决方案:

    我认为当片段实例状态恢复时,与此类片段关联的 nav_graph 的操作的链接会以某种方式丢失或其他什么......但我可能是错的

    在这种情况下,可以直接使用您要导航到的片段的 id,而不是通过安全参数或其 id 指向操作本身。

    在这种情况下,如果您想传递参数,您必须通过捆绑包以老式方式进行。

    Bundle args = new Bundle();
    args.putString(ID_ARG, arg);
    Navigation.findNavController(getView()).navigate(R.id.fragmentId, args);
    

    【讨论】:

    • 我认为这句话非常准确:“我认为当片段实例状态恢复时,与该片段关联的 nav_graph 的操作的链接会以某种方式丢失”。 1.0.0-alpha07 中仍然存在此问题
    • 直接使用要导航到的fragment的ID有一些缺点。在片段恢复时,你的后栈将被完全破坏。但是,它确实解决了抛出无意义异常的直接问题......
    • 我仍然得到这个无意义的异常。导航第一次工作。然后休息。哇
    【解决方案3】:

    就我而言,这是因为我使用fragmentManager?.popBackStack() 向后导航,而不是像下面这样正确导航:

    Navigation.findNavController(activity!!, R.id.fragment_container).navigate(
                    Navigation.findNavController(activity!!, R.id.fragment_container).graph.startDestination)
    

    【讨论】:

      【解决方案4】:

      就我而言,我通过替换来解决问题 -

       <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" />
      

      【讨论】:

        猜你喜欢
        • 2018-12-06
        • 1970-01-01
        • 2020-03-01
        • 2020-08-24
        • 2021-09-12
        • 2020-11-06
        • 2020-02-29
        • 1970-01-01
        • 2020-08-08
        相关资源
        最近更新 更多