5

Tengo un controlador que muestra un DialogFragment cuando recibe un mensaje en particular. Esto generalmente funciona, pero si el fragmento ya se ha guardado, me sale el siguiente error:Cómo mostrar un DialogFragment desde un controlador

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)

Ahora, sé que esto se espera que, con base en el Javadoc para 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.

Mi problema es que no puedo decir cómo prevenirlo. Intenté llamar al Handler.removeMessages() en onPause(), pero todavía ocurre. Intenté establecer una marca en onSaveInstanceState() y no mostrar el fragmento si está configurado, pero aún así aparece. Esto parece ser un problema bastante común, pero no puedo encontrar una solución que funcione. Básicamente, ¿cómo sé que el fragmento ya se ha guardado?

Por cierto, esto ocurre en mi BaseActivity (amplía FragmentActivity), pero cada actividad tiene su propio controlador, por lo que no creo que esto sea un problema.

Mi última idea es usar Fragment.commitAllowingStateLoss(), pero parece un truco.

EDIT: Aquí está el código que me está causando problemas:

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; 
     } 
     } 
}; 
+0

En general, se considera que es mala experiencia de usuario para mostrar un cuadro de diálogo abruptamente en momentos aleatorios como este, por lo que antes de intentar difícil encontrar un trabajo alrededor , Reconsideraría tu diseño. Consulte [** publicación de blog **] (http://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html) sobre este tema para obtener más información. –

Respuesta

1

asumo en mi respuesta que está utilizando FragmentManager y añadir fragmentos a través FragmentTransacts con etiquetas (o identificaciones). así que básicamente dentro de su BaseActivity usted podría hacer algo como esto

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 
} 
+0

No, el fragmento que intento agregar nunca existe. Es un FragmentDialog que solo se crea cuando recibo el mensaje. Añadiré un código. –

+2

Aunque nunca he visto este problema que causa este mensaje de error, definitivamente debe probar lo que sugiere Rafael. Si dice "nunca existe", tal vez existió algún otro diálogo. Cambie su etiqueta de "diálogo" a "this_specific_dialog" –

+0

Excelente. Tenía algunos diálogos diferentes con la misma etiqueta. Buena respuesta/comentario. – Knossos

Cuestiones relacionadas