我在调用finish()然后重新打开应用程序时遇到上述错误。这是管理导航onBackPressed()的代码。
android.app.FragmentManager settingsFragmentManager = getFragmentManager();
FragmentManager fragmentManager = getSupportFragmentManager();
if (settingsFragmentManager.getBackStackEntryCount() > 0)
settingsFragmentManager.popBackStackImmediate();
else if (fragmentManager.getBackStackEntryCount() > 0)
fragmentManager.popBackStackImmediate();
if (fragmentManager.getBackStackEntryCount() == 0 && endIfEmpty) finish();
if (fragmentManager.getBackStackEntryCount() == 0 && !endIfEmpty) loadView(0);
if (fragmentManager.getBackStackEntryCount() == 0 && !userHasLoggedIn)
{
LocalBroadcastManager.getInstance(getApplicationContext()).unregisterReceiver(loginBroadcastReceiver);
finish();
}
loadView调用方法负责根据用户选择的内容添加片段。当以0作为参数调用它时,它会添加默认片段。
这个方法:
private void loadView(int position)
{
FragmentManager fragmentManager = getSupportFragmentManager();
Bundle fragmentArgs = new Bundle();
if (drawerOpened)
mDrawerLayout.closeDrawer(drawerHolderLayout);
switch (position) {
case 0:
ProfileEditFragment activityList = new ProfileEditFragment();
fragmentArgs.clear();
fragmentArgs.putString(ProfileEditFragment.ARG_AGENT_ID, String.valueOf(prefClass.getAgentId()));
fragmentArgs.putString(ProfileEditFragment.ARG_USERNAME, prefClass.getUsername());
fragmentArgs.putString(ProfileEditFragment.ARG_PASSWORD, prefClass.getHashedPassword());
fragmentArgs.putInt(ProfileEditFragment.ARG_OPERATION, ProfileEditFragment.LOAD_ALL_DATA);
activityList.setArguments(fragmentArgs);
fragmentManager.beginTransaction().add(R.id.main_activity_content, activityList).addToBackStack(null).commit();
//activityList.retrieveActivityFromServer(ProfileEditFragment.LOAD_ALL_DATA);
break;
}
}
执行此行时发生异常:
fragmentManager.beginTransaction().add(R.id.main_activity_content, activityList).addToBackStack(null).commit();
但是,当应用程序首次启动时,不会发生此异常。它仅在调用finish()后重新启动时出现。值得一提的是,添加的第一个片段是LoginFragment。登录过程完成后,调用popBackstack,backstack变为空,并调用loadView(0)。那么,为什么在调用loadView时会出现异常,但在添加LoginFragment时却没有?
提前致谢。
答案 0 :(得分:1)
就我而言,在应用程序移至后台后,我打开了一个DialogFragment。
您可以通过以下方式模拟此状态:打开请求,运行Thread.sleep(2000)
,快速按智能手机上的“关闭电源”(或按“菜单”按钮),然后按“打开电源”(或打开应用程序) 。如果请求带来错误并显示DialogFragment,它将在日志中写入:java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
,对应的行是dialogFragment.show(supportFragmentManager, TAG)
。
我尝试了一种解决方案https://stackoverflow.com/a/22414366/2914140,它可以正常工作,但包含此错误。因此,再添加一张支票:
if (supportFragmentManager?.isStateSaved == false) {
dialogFragment.show(supportFragmentManager, TAG)
}
在关闭屏幕,只需打开你不会看到这个对话框(伤感地说),但您的应用程序不会崩溃后,这种情况下。
更新
对不起,旧答案已经过时。参见On showing dialog i get "Can not perform this action after onSaveInstanceState"。
public class CustomDialogFragment extends DialogFragment {
@Override
public void show(FragmentManager manager, String tag) {
try {
FragmentTransaction ft = manager.beginTransaction();
ft.add(this, tag);
ft.commit();
} catch (IllegalStateException e) {
}
}
}
在这种情况下,将显示对话框片段。
答案 1 :(得分:0)
您确定在您认为的Activity实例上发生了Fragment提交吗?
我不确定我的情况是否适用于您,但我确实有类似的症状,因为我在停止并重新启动活动后才会看到异常。我还发现亚历克斯洛克伍德(非常优秀)关于这个主题的文章似乎没有帮助我,就像你在评论中提到的那样。
无论如何,我最终意识到我通过初始化一个长生命对象(在我的情况下是一个Facebook会话对象)并为它提供了一个对回调活动的引用来引发这个异常。如果Session.getActiveSession()表明会话不可用,我只会初始化会话对象。这意味着我第二次启动Activity时,将使用上一个Activity的会话,以及指向前一个Activity的回调。之前的Activity已经被销毁并且具有onSaveInstanceState。当触发回调时,旧的Activity将尝试启动其Fragment,并且发生异常。当 new Activity处于Fragment提交的有效状态时,我一直在试图弄明白我为什么会得到这个异常,但我一直试图将一个片段提交给一个旧的自从被破坏的活动。
你本身可能没有使用Facebook会话,但也许你正在做一些与长期生活对象类似的事情?
祝你好运!