我有一个处理程序,它在收到特定消息时显示一个 DialogFragment。这通常有效,但如果片段已被保存,我会收到以下错误:
E/AndroidRuntime(3898):致命异常:主要 E/AndroidRuntime(3898):java.lang.IllegalStateException:onSaveInstanceState 后无法执行此操作 E/AndroidRuntime(3898):在 android.support.v4.app.FragmentManagerImpl.checkStateLoss (FragmentManager.java:1299) E/AndroidRuntime(3898): 在 android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1310) E/AndroidRuntime(3898): 在 android.support.v4.app.BackStackRecord .commitInternal(BackStackRecord.java:541) E/AndroidRuntime(3898): 在 android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:525) E/AndroidRuntime(3898): 在 android.support.v4.app .DialogFragment.show(DialogFragment.java:123) E/AndroidRuntime(3898): 在 com.malauzai.app.BaseActivity$2.handleMessage(BaseActivity.java:72) E/AndroidRuntime(3898): 在 android.os。Handler.dispatchMessage(Handler.java:99)
现在,我知道这是预期的,基于 FragmentManager.beginTransaction 的 Javadoc:
注意:片段事务只能在活动保存其状态之前创建/提交。如果您尝试在 Activity.onSaveInstanceState() 之后(以及在随后的 Activity.onStart 或 Activity.onResume() 之前提交事务,您将收到错误消息。这是因为框架负责将您当前的片段保存在状态中,如果在保存状态后进行更改,那么它们将丢失。
我的问题是我不知道如何防止它。我试过打电话Handler.removeMessages()
,onPause()
但它仍然会发生。我已经尝试设置一个标志onSaveInstanceState()
并且如果设置了该片段则不显示该片段,但它仍然会发生。这似乎是一个很常见的问题,但我想不出一个可行的解决方案。基本上,我怎么知道片段已经被保存了?
顺便说一句,这发生在我的 BaseActivity(扩展 FragmentActivity)上,但每个活动都有自己的处理程序,所以我不认为这应该是一个问题。
我最后的想法是使用Fragment.commitAllowingStateLoss()
,但这似乎是一个 hack。
编辑: 这是导致我出现问题的代码:
private final Handler mTimerHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case TIMER_MESSAGE_LOGOUT_WARNING:
// throws IllegalStateException if fragment is already saved
new LogoutWarningDialog().show(getSupportFragmentManager(),
"dialog");
break;
}
}
};