【问题标题】:ANDROID - java.lang.IllegalStateException: cannot perform this action after onSaveInstanceStateANDROID - java.lang.IllegalStateException:在 onSaveInstanceState 之后无法执行此操作
【发布时间】:2015-04-02 00:33:14
【问题描述】:

我在调用 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();

但是,第一次启动应用程序时不会发生此异常。它仅在调用完成()后重新启动时出现。值得一提的是,添加的第一个片段是一个LoginFragment。登录过程完成后,将调用 popBackstack,backstack 变为空并调用 loadView(0)。那么,为什么调用loadView的时候会崩溃,而添加LoginFragment的时候却没有呢?

提前致谢。

【问题讨论】:

  • 感谢您的回复,我以前读过 Alex Lockwood 的帖子,这就是我在 onPostResume 中进行交易的原因。正如我所说,我第一次启动该应用程序时一切正常。添加了 LoginFragment,登录完成且没有错误,调用 popBackStack,它变为空并且添加了 ActivityFragment 没有问题。但是如果用户离开应用程序(finish() 被调用)然后重新打开它,LoginFragment 被添加,popBackStack 被调用,它变为空并且当我尝试添加 ActivityFragment 时发生异常。为什么我第二次可以添加LoginFragment,但不能添加ActivityFragment?
  • 我现在正在经历同样的问题。我读过亚历克斯洛克伍德的帖子,但它们似乎不适用于我的情况。如果我退出并从我的 Facebook 登录/注册活动返回,我只会看到这个问题。还在研究中……
  • @TommyVisic 如果您看到此内容,请通过 Skype 与我联系:phiter_fernandes。我需要和你谈谈你多年前制作的游戏。

标签: java android android-fragments illegalstateexception


【解决方案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) {
        }
    }
}

在这种情况下,将显示对话框片段。

【讨论】:

    【解决方案2】:

    您确定 Fragment 提交发生在您认为的 Activity 实例上吗?

    我不确定我的情况是否适用于您,但我确实有类似的症状,因为我只会在停止并重新启动 Activity 后看到异常。我还发现 Alex Lockwood 关于该主题的(非常出色的)文章似乎对我没有帮助,就像您在 cmets 中提到的那样。

    无论如何,我最终意识到我是通过初始化一个长期存在的对象(在我的例子中是 Facebook 会话对象)并为它提供对回调的 Activity 的引用而导致了这个异常。如果 Session.getActiveSession() 指示会话不可用,我只会初始化会话对象。这意味着我第二次启动 Activity 时,将使用前一个 Activity 的会话,以及指向前一个 Activity 的回调。之前的 Activity 已被销毁并具有其 onSaveInstanceState。当回调被触发时,旧的 Activity 会尝试打开它的 Fragment,然后就发生了异常。我一直在绞尽脑汁试图弄清楚为什么当 new Activity 处于 Fragment 提交的有效状态时我会收到此异常,但一直以来我都试图将 Fragment 提交给旧的, 自销毁的 Activity。

    您可能没有使用 Facebook 会话本身,但也许您正在对一个长期存在的对象做类似的事情?

    祝你好运!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-25
      • 1970-01-01
      • 2013-11-25
      • 1970-01-01
      相关资源
      最近更新 更多