我有一个Live Android应用程序,从市场上我收到了以下堆栈跟踪,我不知道为什么它会发生,因为它不是发生在应用程序代码中,而是由应用程序的一些或其他事件引起的(假设)

我没有使用片段,仍然有一个FragmentManager的参考。 如果有人能揭示一些隐藏的事实,以避免这类问题:

java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1109)
at android.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:399)
at android.app.Activity.onBackPressed(Activity.java:2066)
at android.app.Activity.onKeyDown(Activity.java:1962)
at android.view.KeyEvent.dispatch(KeyEvent.java:2482)
at android.app.Activity.dispatchKeyEvent(Activity.java:2274)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1668)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1720)
at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1258)
at android.app.Activity.dispatchKeyEvent(Activity.java:2269)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1668)
at android.view.ViewRoot.deliverKeyEventPostIme(ViewRoot.java:2851)
at android.view.ViewRoot.handleFinishedEvent(ViewRoot.java:2824)
at android.view.ViewRoot.handleMessage(ViewRoot.java:2011)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:132)
at android.app.ActivityThread.main(ActivityThread.java:4025)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:491)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
at dalvik.system.NativeStart.main(Native Method)  

当前回答

这是我迄今为止遇到的最愚蠢的错误。我有一个片段应用程序工作完美的API < 11,并强制关闭API > 11。

我真的不知道他们在saveInstance调用的活动生命周期内改变了什么,但我在这里是我如何解决这个问题的:

@Override
protected void onSaveInstanceState(Bundle outState) {
    //No call for super(). Bug on API Level > 11.
}

我只是不调用.super(),一切都很好。我希望这将为您节省一些时间。

编辑:经过进一步研究,这是支持包中的一个已知错误。

如果你需要保存实例,并添加一些东西到你的outState Bundle,你可以使用以下方法:

@Override
protected void onSaveInstanceState(Bundle outState) {
    outState.putString("WORKAROUND_FOR_BUG_19917_KEY", "WORKAROUND_FOR_BUG_19917_VALUE");
    super.onSaveInstanceState(outState);
}

EDIT2:如果您试图在Activity在后台消失后执行事务,也可能会发生这种情况。为了避免这种情况,你应该使用commitAllowingStateLoss()

EDIT3: The above solutions were fixing issues in the early support.v4 libraries from what I can remember. But if you still have issues with this you MUST also read @AlexLockwood 's blog : Fragment Transactions & Activity State Loss Summary from the blog post (but I strongly recommend you to read it) : NEVER commit() transactions after onPause() on pre-Honeycomb, and onStop() on post-Honeycomb Be careful when committing transactions inside Activity lifecycle methods. Use onCreate(), onResumeFragments() and onPostResume() Avoid performing transactions inside asynchronous callback methods Use commitAllowingStateLoss() only as a last resort

其他回答

我得到这个异常时,我按下后退按钮取消意图选择器在我的地图片段活动。 我通过替换onResume()的代码来解决这个问题(我在那里初始化片段和提交事务)到onStart(),应用程序现在工作正常。 希望能有所帮助。

My use case: I have used listener in fragment to notify activity that some thing happened. I did new fragment commit on callback method. This works perfectly fine on first time. But on orientation change the activity is recreated with saved instance state. In that case fragment is not created again implies that the fragment have the listener which is old destroyed activity. Any way the call back method will get triggered on action. It goes to destroyed activity which cause the issue. The solution is to reset the listener in fragment with current live activity. This solve the problem.

这是我迄今为止遇到的最愚蠢的错误。我有一个片段应用程序工作完美的API < 11,并强制关闭API > 11。

我真的不知道他们在saveInstance调用的活动生命周期内改变了什么,但我在这里是我如何解决这个问题的:

@Override
protected void onSaveInstanceState(Bundle outState) {
    //No call for super(). Bug on API Level > 11.
}

我只是不调用.super(),一切都很好。我希望这将为您节省一些时间。

编辑:经过进一步研究,这是支持包中的一个已知错误。

如果你需要保存实例,并添加一些东西到你的outState Bundle,你可以使用以下方法:

@Override
protected void onSaveInstanceState(Bundle outState) {
    outState.putString("WORKAROUND_FOR_BUG_19917_KEY", "WORKAROUND_FOR_BUG_19917_VALUE");
    super.onSaveInstanceState(outState);
}

EDIT2:如果您试图在Activity在后台消失后执行事务,也可能会发生这种情况。为了避免这种情况,你应该使用commitAllowingStateLoss()

EDIT3: The above solutions were fixing issues in the early support.v4 libraries from what I can remember. But if you still have issues with this you MUST also read @AlexLockwood 's blog : Fragment Transactions & Activity State Loss Summary from the blog post (but I strongly recommend you to read it) : NEVER commit() transactions after onPause() on pre-Honeycomb, and onStop() on post-Honeycomb Be careful when committing transactions inside Activity lifecycle methods. Use onCreate(), onResumeFragments() and onPostResume() Avoid performing transactions inside asynchronous callback methods Use commitAllowingStateLoss() only as a last resort

简单有效的解决方案:

遵循简单的步骤:

步骤1:在各自的片段中覆盖onSaveInstanceState状态。并从中移除super method。

@Override
public void onSaveInstanceState(Bundle outState) {
};

步骤2:使用CommitAllowingStateLoss();而不是commit();而片段操作。

fragmentTransaction.commitAllowingStateLoss();

当用户旋转屏幕以便加载与新方向相关的资源时,onSaveInstance将被调用。

有可能这个用户旋转了屏幕,然后按了后退按钮(因为也有可能这个用户在使用你的应用程序时摸不着他们的手机)