Как отобразить DialogFragment из обработчика - PullRequest
5 голосов
/ 02 февраля 2012

У меня есть обработчик, который отображает 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;
        }
      }
};

1 Ответ

1 голос
/ 02 февраля 2012

В моем ответе я предполагаю, что вы используете FragmentManager и добавляете Fragments через FragmentTransacts с тегами (или идентификаторами). так что в основном внутри вашего BaseActivity вы можете просто сделать что-то вроде этого

FragmentManager manager = getFragmentSupportedManager();
Fragment fragmentIWannaKnowIfexists = manager.findFragmentByTag("Tag I used to create this Fragment inside FragmentTrasnsaction")
// or manager.findFragmentById(ID_FROM_LAYOUT)
if(fragmentIWannaKnowIfexists != null){
    //we have this Fragment already
} else {
    // this Fragment was not added already
}
...