我有一个Handler,当它接收到特定的消息时会显示一个DialogFragment。通常情况下这个方法是有效的,但如果该片段已经被保存了,则会出现以下错误:
E/AndroidRuntime( 3898): FATAL EXCEPTION: main E/AndroidRuntime( 3898): java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState E/AndroidRuntime( 3898): at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1299) E/AndroidRuntime( 3898): at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1310) E/AndroidRuntime( 3898): at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:541) E/AndroidRuntime( 3898): at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:525) E/AndroidRuntime( 3898): at android.support.v4.app.DialogFragment.show(DialogFragment.java:123) E/AndroidRuntime( 3898): at com.malauzai.app.BaseActivity$2.handleMessage(BaseActivity.java:72) E/AndroidRuntime( 3898): at android.os.Handler.dispatchMessage(Handler.java:99)
现在,根据FragmentManager.beginTransaction的Javadoc,我知道这是预期的:
注意:只能在活动保存其状态之前创建/提交片段事务。如果在Activity.onSaveInstanceState()之后(并在以下Activity.onStart或Activity.onResume()之前)尝试提交事务,则会出错。这是因为框架会负责在状态中保存当前片段,如果在保存状态后进行更改,则它们将丢失。
我的问题是我不知道如何防止这种情况发生。我已经尝试在onPause()中调用Handler.removeMessages(),但仍然出现了错误。我已经尝试在onSaveInstanceState()中设置一个标志,如果设置了就不显示片段,但仍然出现了错误。这似乎是一个很常见的问题,但我找不到解决方法。基本上,我如何知道该片段已经被保存?
顺便说一下,这发生在我的BaseActivity(扩展FragmentActivity)上,但每个活动都有自己的处理程序,所以我认为这不应该是一个问题。
我最后的想法是使用Fragment.commitAllowingStateLoss(),但那似乎是一个hack。
编辑:以下是引起问题的代码:
E/AndroidRuntime( 3898): FATAL EXCEPTION: main E/AndroidRuntime( 3898): java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState E/AndroidRuntime( 3898): at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1299) E/AndroidRuntime( 3898): at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1310) E/AndroidRuntime( 3898): at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:541) E/AndroidRuntime( 3898): at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:525) E/AndroidRuntime( 3898): at android.support.v4.app.DialogFragment.show(DialogFragment.java:123) E/AndroidRuntime( 3898): at com.malauzai.app.BaseActivity$2.handleMessage(BaseActivity.java:72) E/AndroidRuntime( 3898): at android.os.Handler.dispatchMessage(Handler.java:99)
现在,根据FragmentManager.beginTransaction的Javadoc,我知道这是预期的:
注意:只能在活动保存其状态之前创建/提交片段事务。如果在Activity.onSaveInstanceState()之后(并在以下Activity.onStart或Activity.onResume()之前)尝试提交事务,则会出错。这是因为框架会负责在状态中保存当前片段,如果在保存状态后进行更改,则它们将丢失。
我的问题是我不知道如何防止这种情况发生。我已经尝试在onPause()中调用Handler.removeMessages(),但仍然出现了错误。我已经尝试在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;
}
}
};