У меня есть обработчик, который отображает DialogFragment при получении определенного сообщения. Обычно это работает, но если фрагмент уже был сохранен, я получаю следующую ошибку:
E/AndroidRuntime (3898): НЕИСПРАВНОЕ ИСКЛЮЧЕНИЕ: main 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. диспетчерское сообщение (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;
}
}
};