重新打开并替换Fragment时,Android应用程序崩溃。

5

我正在编写的应用程序中,我已经实现了导航抽屉 (默认 Android 的向后兼容方式)。所以从导航抽屉中选择菜单元素然后我会这样做(addPreviousToBackStack 对于测试始终为false):

private void replaceFragment(final Fragment fragment, final boolean addPreviousToBackStack) {
    FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    fragmentTransaction.replace(R.id.activity_main_fragment_container, fragment);
    if(addPreviousToBackStack) {
        fragmentTransaction.addToBackStack(fragment.getTag());
    }
    fragmentTransaction.commit();
    currentFragment = fragment;
}

当我启动应用程序时,一切正常。然后我使用返回按钮关闭了应用程序。如果我重新打开应用程序(无论如何:通过长按主页按钮或通过快捷方式),应用程序将在初始屏幕上启动(调用onCreate),然后我打开导航抽屉并选择一个菜单项,此时应用程序会崩溃。
这是我的异常提示:"java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState",它恰好发生在我执行以下代码的那一行:
fragmentTransaction.commit();

我不知道为什么在应用程序重新打开时出现这个问题,而在初始打开应用程序时却没有。有任何提示吗?


这是一个Android老问题 :) 也许我在类似问题的回答可以帮到你。 - gunar
哦,你提供的所有正统或非正统的方法都不适用于我。我正在尝试在4.3设备(Galaxy Nexus)上运行。 - dirkvranckaert
1个回答

1

我不确定你使用的情况,但调用fragmentTransaction.commitAllowStateLoss();不应再导致崩溃。但是,您需要承担状态信息在片段上丢失的风险。



此外,currentFragment = fragment;这行代码似乎是内存泄漏的原因。如果Android想要清理片段,您将通过保留对片段的强引用来阻止它。不要使用它...


添加fragmentTransaction.commitAllowStateLoss();并没有起作用,它仍然像之前一样崩溃...那么我应该如何保留对fragment的引用呢?有时我需要与fragment进行交互,这就是为什么我将其保留在那里的原因... - dirkvranckaert
getFragmentById(R.id.activity_main_fragment_container) 是获取 Fragment 实例的方法。如果您需要访问特定的方法,则需要将其向上转型为您的 Fragment 类。 - gunar
我再次使用commitAllowStateLoss()进行了测试,似乎这给了我一个Caused by: java.lang.IllegalStateException: Activity has been destroyed异常。 - dirkvranckaert
很容易解决:检查 getActivity() 是否为空。 - gunar
这段代码是在activity中运行的,因此activity永远不会为空。我尝试使用if(!this.isFinishing){}进行包围,似乎可以解决问题,但我不确定是否可以信任这个修复方法。有人能确认一下吗? - dirkvranckaert
你能透露更多的代码吗?我对你调用 replaceFragment(...) 方法的上下文很感兴趣。 - gunar

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