Mam Handler, który wyświetla DialogFragment po otrzymaniu określonej wiadomości. To zazwyczaj działa, ale jeśli fragment został już zapisany, pojawia się następujący błąd:Jak wyświetlić DialogFragment z Handler'a
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)
Teraz wiem, że to jest z oczekiwaniami, na podstawie Javadoc dla FragmentManager.beginTransaction:
Note: A fragment transaction can only be created/committed prior to an activity saving its state. If you try to commit a transaction after Activity.onSaveInstanceState() (and prior to a following Activity.onStart or Activity.onResume(), you will get an error. This is because the framework takes care of saving your current fragments in the state, and if changes are made after the state is saved then they will be lost.
Moim problemem jest to, że nie umiem tego powstrzymać. Próbowałem wywoływać Handler.removeMessages()
na onPause()
, ale nadal występuje. Próbowałem ustawić flagę w onSaveInstanceState()
i nie pokazano fragmentu, jeśli jest ustawiony, ale nadal występuje. Wydaje się, że jest to dość powszechny problem, ale nie mogę wymyślić rozwiązania, które działa. Zasadniczo, skąd mam wiedzieć, że fragment został już zapisany?
BTW, to zdarza się na mojej BaseActivity (rozszerza FragmentActivity), ale każde działanie ma swój własny handler, więc nie sądzę, że to powinien być problem.
Moja ostatnia myśl jest przy użyciu Fragment.commitAllowingStateLoss()
, ale to wygląda jak włamanie.
EDIT: Oto kod, który jest przyczyną mnie problemów:
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;
}
}
};
Generalnie uważa się za złe doświadczenia użytkownika, aby wyświetlić okno dialogowe nagle w przypadkowych chwilach takich jak ta, więc zanim spróbujesz trudno znaleźć pracę wokół , Przemyślałbym twój projekt. Więcej informacji na ten temat można znaleźć w [** postach na blogu **] (http://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html). –