У меня есть обработчик, который отображает 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)
Теперь я знаю, что это ожидается, основываясь на Javadoc для FragmentManager.beginTransaction:
Примечание. Фрагмент транзакции может быть создан / зафиксирован только до того, как операция сохранит свое состояние. Если вы попытаетесь зафиксировать транзакцию после Activity.onSaveInstanceState () (и до следующего Activity.onStart или Activity.onResume (), вы получите ошибку. Это связано с тем, что платформа заботится о сохранении ваших текущих фрагментов в состоянии и если изменения будут сделаны после сохранения состояния, они будут потеряны.
Моя проблема в том, что я не могу сказать, как это предотвратить. Я пытался позвонить Handler.removeMessages()
на onPause()
, но это все еще происходит. Я попытался установить флаг в onSaveInstanceState()
и не показывать фрагмент, если он установлен, но он все еще происходит. Это кажется довольно распространенной проблемой, но я не могу найти решение, которое работает. Как узнать, что фрагмент уже был сохранен?
Кстати, это происходит с моей BaseActivity (расширяет FragmentActivity), но у каждого действия есть свой собственный обработчик, поэтому я не думаю, что это должно быть проблемой.
Моя последняя мысль - использовать Fragment.commitAllowingStateLoss()
, но это похоже на взлом.
EDIT:
Вот код, который вызывает у меня проблемы:
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;
}
}
};