忽略 navigate() 调用:FragmentManager 已经保存了它的状态

Ignoring navigate() call: FragmentManager has already saved its state

我在 MainActivity 中使用 navigation,然后我开始 SecondActivity(为了结果)。 SecondActivity 完成后,我想在 MainActivity 中继续导航,但是 FragmentManager 已经保存了他的状态。

Navigation.findNavController(view).navigate(R.id.action_next, bundle) 我收到日志消息:

Ignoring navigate() call: FragmentManager has already saved its state

如何继续导航?

我是这样解决这个问题的:

    @Override
public void onActivityResult() { //inside my fragment that started activity for result
        model.navigateToResults = true; //set flag, that navigation should be performed
}

然后

    @Override
public void onResume() { //inside fragment that started activity for result
    super.onResume();

    if(model.navigateToResults){
        model.navigateToResults = false;
        navController.navigate(R.id.action_startFragment_to_resultsFragment);
    }
}

不确定,如果这不是一个糟糕的黑客攻击,但它对我有用。 FramgentManager 状态在此时恢复 (onResume),导航没有问题。

最后,我在导航到恢复状态之前通过简单调用 super.onPostResume() 解决了这个问题。

您必须始终在 Activity 的 onActivityResult 中调用 super.onActivityResult()。那就是:

  1. 解锁碎片以便它们可以进行碎片交易(即避免state is already saved错误)

  2. 调度 onActivityResult 调用 startActivityForResult 的片段的回调。

我相信上述解决方案应该有效。但我的问题是不同的。有一个第三方 sdk 正在使用我提供的上下文启动它的 activity,它正在我必须实现的侦听器上传递结果。

所以我没有选择 onActivityResult :(

我使用下面的 hack 来解决问题:

   private var runnable: Runnable? = null // Runnable object to contain the navigation code

    override fun onResume() {
        super.onResume()

        // run any task waiting for this fragment to be resumed
        runnable?.run()
    }


    override fun responseListener(response: Response) {    // Function in which you are getting response

        if (!isResumed) {    
            // add navigation to runnable as fragment is not resumed
            runnable = Runnable {
                navController.navigate(R.id.destination_to_navigate)
            }
        } else {
            // navigate normally as fragment is already resumed
            navController.navigate(R.id.destination_to_navigate)
        }
    }


让我知道是否有更好的解决方案。目前我发现这非常简单且易于实现:)

在导航前调用 super.onPostResume()....正在运行