2010-02-26 14 views
12

1) lanzo una tarea de fondo (a través de AsyncTask)Descartar de diálogo después del cambio de orientación de la pantalla

new FindJourneyTask().execute(); // FindJourneyTask extends AsyncTask 

2) Aún en el hilo principal (justo antes de que se lance nuevo hilo) se crea un diálogo con showDialog (dialogId)

// this method is in FindJourneyTask 
protected void onPreExecute() { 
    showDialog(DIALOG_FINDING_JOURNEY); 
} 

3) los cambios de orientación de la pantalla y la actividad se vuelve a crear

4) ¿Cómo puedo ahora cerrar el diálogo de la FindJourneyTask? Llamar a dismissDialog (dialogId) no hace nada.

// this method is in FindJourneyTask 
protected void onPostExecute(FindJourneyResult result) { 
    dismissDialog(DIALOG_FINDING_JOURNEY); // does nothing 
} 
+0

Publique su código para que podamos ver lo que está haciendo mal. –

Respuesta

22

Este es un problema común, y no hay soluciones realmente buenas. El problema es que al cambiar la orientación de la pantalla, toda la actividad se destruye y vuelve a crear. Al mismo tiempo, el cuadro de diálogo que tenía anteriormente se vuelve a crear en la nueva actividad, pero la tarea de fondo anterior todavía se refiere a la actividad anterior cuando intenta cerrar el cuadro de diálogo. El resultado es que descarta un diálogo que fue destruido hace mucho tiempo, en lugar de descartar el diálogo de la nueva orientación creada.

Hay tres soluciones básicas:

  1. anular el código de orientación-tratamiento por omisión para que su actividad no se destruye después de la rotación. Esta es probablemente la respuesta menos satisfactoria, ya que bloquea una gran cantidad de código que se ejecuta automáticamente en los cambios de orientación.

  2. Cree una variable de miembro estática de su actividad que haga referencia a la actividad en sí, para que pueda llamar al STATIC_ACTIVITY_VARIABLE.dismissDialog().

  3. Codifique una solución en la que la tarea en segundo plano realiza un seguimiento de la actividad actual y se actualiza por sí misma según sea necesario.

Estas tres soluciones se discuten en detalle aquí: http://groups.google.com/group/android-developers/browse_thread/thread/bf046b95cf38832d/

+0

Hice mi diálogo una variable estática dentro de mi actividad, y funciona perfecto ahora. p.ej. static AlertDialog dlg_error = null; – Kevin

10

hay una mejor solución a este problema ahora que implica el uso de fragmentos.

Si crea un cuadro de diálogo usando DialogFragment, este fragmento será responsable de mantener el ciclo de vida de su diálogo. Cuando muestra un cuadro de diálogo, proporciona una etiqueta para su fragmento (DialogFragment.show()). Cuando necesite acceder a su diálogo, simplemente busque el DialogFragment necesario usando FragmentManager.findFragmentByTag en lugar de tener una referencia al cuadro de diálogo.

De esta manera, si el dispositivo cambia de orientación, obtendrá un nuevo fragmento en lugar del anterior, y todo funcionará.

Aquí hay un código basado también en respuesta @peresisUser:

public void onSaveInstanceState(Bundle outState) { 
    AppCompatActivity activity = (AppCompatActivity) context; 
    FragmentManager fragmentManager = activity.getSupportFragmentManager(); 
    DialogFragment dialogFragment = (DialogFragment) fragmentManager.findFragmentByTag("your_dialog_tag"); 
    if(dialogFragment!=null) { 
     Dialog dialog = dialogFragment.getDialog(); 
     if(dialog!=null && dialog.isShowing()) { 
     dialogFragment.dismiss(); 
     } 
    } 
} 
+1

Tengo el mismo problema incluso con fragmentos. Cuando se recrea la actividad e intento encontrar el fragmento por etiqueta, siempre obtengo una referencia nula con el diálogo que se muestra en la nueva actividad O_o – fr4gus

+0

@ fr4gus Probablemente sea un error, tendrás que experimentar con cosas para encontrar una solución alternativa – Malcolm

4

Esto es mucho después de que se hizo la pregunta y respondió, pero me encontré con este problema también y quería compartir mi solución ...

Invoco onSavedInstance() que se ejecuta en cambio de orientación, si el diálogo se muestra o no con dialog.isShowing(), y lo pasa a la variable outState. Luego, en su onCreate(), marque esta var si es verdadera. Si lo es, simplemente descarta su diálogo con el diálogo.despedir()

Espero que esto ayude a los demás :()

Cuestiones relacionadas