Ho un gestore che visualizza un DialogFragment quando riceve un messaggio particolare. Questo di solito funziona, ma se il frammento è già stato salvato, ottengo il seguente errore:Come visualizzare un DialogFragment da un gestore
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)
Ora, so che questo è previsto, sulla base del Javadoc per 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.
Il mio problema è che non posso dire come prevenirlo. Ho provato a chiamare Handler.removeMessages()
su onPause()
, ma si verifica ancora. Ho provato a impostare un flag in onSaveInstanceState()
e non mostrare il frammento se è impostato, ma si verifica ancora. Questo sembra un problema abbastanza comune, ma non riesco a trovare una soluzione che funzioni. In sostanza, come faccio a sapere se il frammento è già stato salvato?
BTW, questo si verifica sul mio BaseActivity (estende FragmentActivity), ma ogni attività ha il proprio gestore, quindi non penso che questo dovrebbe essere un problema.
Il mio ultimo pensiero utilizza Fragment.commitAllowingStateLoss()
, ma sembra un trucco.
EDIT: Ecco il codice che mi sta causando problemi:
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;
}
}
};
Generalmente è considerato come l'esperienza dell'utente male a mostrare una finestra di dialogo bruscamente a volte casuali come questo, quindi prima si tenta di difficile trovare un lavoro in giro , Riconsidererei il tuo design. Vedi questo [** blog post **] (http://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html) su questo argomento per ulteriori informazioni. –