我有一个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)  

当前回答

如果你试图在你的片段活动的onSaveInstanceState()被调用后执行片段转换,就会发生这样的异常。

发生这种情况的一个原因是,当一个活动停止时,如果你让一个AsyncTask(或线程)运行。

调用onSaveInstanceState()后的任何转换都可能丢失,如果系统回收活动的资源并稍后重新创建它。

其他回答

I noticed something very interesting. I have in my app the option to open the phone's gallery and the device asks what app to use, there I click on the gray area away from the dialog and saw this issue. I noticed how my activity goes from onPause, onSaveInstanceState back to onResume, it doesn't happen to visit onCreateView. I am doing transactions at onResume. So what I ended up doing is setting a flag being negated onPause, but being true onCreateView. if the flag is true onResume then do onCommit, otherwise commitAllowingStateLoss. I could go on and waste so much time but I wanted to check the lifecycle. I have a device which is sdkversion 23, and I don't get this issue, but I have another one which is 21, and there I see it.

只需在显示你的片段之前调用super.onPostResume(),或者在调用super.onPostResume()之后在onPostResume()方法中移动你的代码。这就解决了问题!

Android 4.2和支持库的源代码中修正了这个问题。[*]

有关原因(和解决方案)的详细信息,请参阅谷歌错误报告: http://code.google.com/p/android/issues/detail?id=19917

如果你正在使用支持库,那么你不应该担心这个错误(很长时间)[*]。然而,如果你直接使用API(即不使用支持库的FragmentManager),并针对Android 4.2以下的API,那么你将需要尝试一种变通方法。

[*]在撰写本文时,Android SDK管理器仍在分发显示此错误的旧版本。

编辑,我要在这里补充一些澄清,因为我显然把投票反对这个答案的人弄糊涂了。

There are several different (but related) circumstances that can cause this exception to be thrown. My answer above is referring to the specific instance discussed in the question i.e. a bug in Android which has subsequently been fixed. If you're getting this exception for another reason it's because you're adding/removing fragments when you shouldn't be (after fragment states have been saved). If you're in such a situation then perhaps "Nested Fragments - IllegalStateException “Can not perform this action after onSaveInstanceState”" can be of use to you.

读 http://chris-alexander.co.uk/on-engineering/dev/android-fragments-within-fragments/

篇文章。 fragment. isresume()检查帮助我在onDestroyView w/o使用onSaveInstanceState方法。

当一个Fragment或AppCompatActivity的状态通过onSaveInstanceState()保存时,它的UI被认为是不可变的,直到ON_START被调用。在保存状态后尝试修改UI可能会导致应用程序导航状态的不一致,这就是为什么FragmentManager会抛出异常,如果应用程序在保存状态后运行FragmentTransaction。参见commit()了解详细信息。

LiveData通过避免在观察者的关联生命周期至少不是STARTED时调用它的观察者来避免这种边缘情况。在幕后,它在决定调用其观察者之前调用isAtLeast()。