tipos - Android-dismissDialog no descarta el diálogo
tipos de dialogos en android studio (9)
Después de buscar en todo tipo de foros, acabo de hacer lo siguiente:
Llamo al método showDialog (MyDialogID) AND dismissDialog (MyDialogId) fuera del método handleMessage (myMessage) de mi controlador.
Antes de eso, llamé a showDialog en mi método onCreate () - e intenté descartar el cuadro de diálogo en el manejador de mensajes. Por qué esto resolvió el problema, no puedo decir.
Estoy usando showDialog()
y dismissDialog()
para mostrar los diálogos de progreso en mi aplicación. Pasé de crear el cuadro de diálogo y llamar a show()
a usarlo para guardar el estado al cambiar la orientación.
Pero cuando cambio la orientación de dismissDialog()
> paisaje-> retrato, el dismissDialog()
ya no dismissDialog()
el diálogo. El diálogo permanece allí todo el tiempo y necesito presionar el botón Atrás para que desaparezca.
¿Alguna razón por la que se comportaría de esa manera?
Editar
Para solucionar este problema, intenté agregar un removeDialog()
en onDestroy()
para que el cuadro de diálogo no se cree / muestre dos veces y, antes de cambiar la orientación, se elimina el cuadro de diálogo. Intenté agregar declaraciones de log y ver qué pasa
05-21 12:35:14.064: DEBUG/MyClass(193): *************callingShowDialog
05-21 12:35:14.064: DEBUG/MyClass(193): *************onCreareDialog
05-21 12:35:15.385: DEBUG/MyClass(193): *************onSaveInstanceState
05-21 12:35:15.415: DEBUG/MyClass(193): *************onDestroy
05-21 12:35:15.585: DEBUG/MyClass(193): *************callingShowDialog
05-21 12:35:15.585: DEBUG/MyClass(193): *************onCreareDialog
05-21 12:35:15.715: DEBUG/MyClass(193): *************onCreareDialog
05-21 12:35:17.214: DEBUG/MyClass(193): *************onSaveInstanceState
05-21 12:35:17.214: DEBUG/MyClass(193): *************onDestroy
05-21 12:35:17.275: ERROR/WindowManager(193): android.view.WindowLeaked: Activity com.android.MyClass has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@43362088 that was originally added here
05-21 12:35:17.395: DEBUG/MyClass(193): *************callingShowDialog
05-21 12:35:17.395: DEBUG/MyClass(193): *************onCreareDialog
05-21 12:35:17.475: DEBUG/MyClass(193): *************onCreareDialog
Si vemos aquí, inicialmente cuando se muestra la actividad, se llama una vez a onCreateDialog y al cambiar la orientación, se llama a onSaveInstanceState y onDestroy.
Pero después de eso, se llama a onCreateDialog dos veces (una vez por una llamada a showDialog que hago, pero ¿por qué la segunda vez?) Y esto sucede cada vez que cambio la orientación de aquí en adelante.
¿Alguna idea de por qué sucede eso?
Gracias de nuevo
Después de presionar el botón de inicio y navegar a la aplicación morelocal (cambiar el idioma del dispositivo), cuando regresé a mi aplicación, los nuevos cuadros de diálogo no se pudieron cerrar a través de la función de desconexión de diálogos (inicié el diálogo desde la actividad en Crear).
La solución fue llamar removeDialog en lugar de dissmissDialog (). Esto ha sido recomendado por Harri arriba, muchas gracias.
He creado un informe de error de Android:
La solución es crear su diálogo usando OnPostCreate en lugar de OnCreate. Agregué esa información al informe de errores y recomendé mejorar la documentación del diálogo .
Estaba experimentando el mismo problema. Estaba creando un AlertDialog
y un ProgressDialog
dentro de la devolución de llamada onCreateDialog()
y mostrándolos desde el onCreate()
. ¡Crear estos diálogos directamente en onCreate
(sin usar onCreateDialog()
) y descartarlos en onPause()
funcionó para mí! Basado en https://.com/a/5693467/955619
La mejor solución para mí parece usar removeDialog (id) en lugar de dismissDialog (); Menos reutilización de esta manera, pero más segura (no arroja nada) y sin problemas al cambiar la orientación.
Me he encontrado con esto al mostrar un cuadro de diálogo en el reemplazo de onCreate de la Actividad. Intente mover el código que hace que el diálogo se muestre en la anulación onPostCreate en su lugar. Esto parece funcionar para mí.
Perdí más de un día en un problema como este con los diálogos que no se descartaron al llamar a desconexión de diálogo. Ocurrió después de mi primera rotación de pantalla y nunca funcionó después. Había estado usando una AsyncTask externa a la que se le pasó una referencia al estado explícitamente.
Al final, la solución fue realmente simple ... removeDialog(int)
lugar de los dismissDialog(int)
.
Me había pasado lo que parecía una eternidad demostrando que me estaba despidiendo de la actividad correcta y revisando la cantidad de veces que se llamaban las cosas, etc., pero fue causada por algunas de las personas que están detrás de las escenas.
Recientemente me encontré con este problema también. Tengo una aplicación con muchas actividades que necesitan acceder a objetos globales (conexiones de base de datos, listas de datos, etc.) y por eso anulé la clase de aplicación. Con ese fin, me di cuenta de que todo lo que necesitaba era una referencia a la última instancia del diálogo de progreso en mi tabla de ejecución que estaba usando para descartar el diálogo. Esto es lo que se me ocurrió y sobrevive con gracia las reorientaciones telefónicas:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
mHandler = new Handler();
mApplication = (MyApplication)getApplication();
mFileStorage = (CheckBoxPreference)getPreferenceScreen().findPreference("fileStorage");
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setTitle("Location Update");
mProgressDialog.setMessage("Moving databases to new storage location.");
mProgressDialog.setIndeterminate(true);
mProgressDialog.setCancelable(false);
mProgressDialog.setCanceledOnTouchOutside(false);
mApplication.setProgressDialog(mProgressDialog);
}
@Override
protected void onResume() {
super.onResume();
mPreferences = PreferenceManager.getDefaultSharedPreferences(this);
mPreferences.registerOnSharedPreferenceChangeListener(this);
if (sUpdateThread != null && sUpdateThread.isAlive()) {
mProgressDialog.show();
}
}
@Override
protected void onPause() {
super.onPause();
mPreferences.unregisterOnSharedPreferenceChangeListener(this);
if (sUpdateThread != null && sUpdateThread.isAlive()) {
mProgressDialog.hide();
mApplication.setProgressDialog(null);
}
}
.... cosas al azar aqui ....
private Runnable showProgressRunnable = new Runnable() {
public void run() {
mProgressDialog.show();
}
};
private Runnable hideProgressRunnable = new Runnable() {
public void run() {
if (mApplication.getProgressDialog() != null) {
mApplication.getProgressDialog().dismiss();
}
}
};
Mi hilo hace un mHandler.post (showProgressRunnable) cuando la tarea comienza y luego hace un mHandler.post (hideProgressRunnable) cuando la tarea termina. Como la referencia al último ProgressDialog ahora está almacenada en la clase de aplicación, puedo cerrarla de manera confiable ya que ya no me aferro a una referencia de objeto anterior.
Enlace para la posteridad: http://developer.android.com/reference/android/app/Application.html
Tenga en cuenta que cada vez que cambie la orientación, se creará una nueva instancia de su Activity
(y, en consecuencia, de su Dialog
través de onCreateDialog
). Puede verificar esto agregando una declaración de registro en cualquiera de los constructores.
Aunque es difícil de decir sin tener que echar un vistazo a su código, supongo que está llamando a dismissDialog
en una instancia anterior de su Activity
.
Considere la siguiente Activity
que simplemente muestra un cuadro de Dialog
vacío cuando se hace clic en un botón e inicia una TimerTask
de TimerTask
para descartarla después de 10 segundos:
public class Test extends Activity {
private Dialog dialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
Button btn = (Button) findViewById(R.id.testButton);
btn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
new Timer().schedule(new TimerTask() {
@Override public void run() { dialog.dismiss(); }
}, 10000);
Test.this.showDialog(1);
}
});
}
@Override
protected Dialog onCreateDialog(int id) {
if(id == 1) {
if(dialog == null) { dialog = new Dialog(this); }
return dialog;
}
return super.onCreateDialog(id);
}
}
Este código tiene un problema similar al que está describiendo: si, durante los 10 segundos, la orientación cambia, el Dialog
nunca se descarta. ¿Por qué? Debido a que en el momento en que se run
TimerTask
se TimerTask
un conjunto completamente diferente de instancias de Test
y Dialog
(durante el cambio de orientación) y la variable de instancia de dialog
TimerTask
referencia a una instancia de Test
que es diferente de la que está actualmente activa en pantalla.
Obviamente, hay varias formas de solucionar este problema (principalmente dependiendo de su aplicación), una forma rápida (¿sucia?) De solucionar el código anterior sería simplemente hacer que el campo de dialog
static
:
private static Dialog dialog;
private AlertDialog alert11 = null;
public void gpsDialog(){
if (alert11 == null || !alert11.isShowing()) {
AlertDialog.Builder builder1 = new AlertDialog.Builder(MainActivity.this);
builder1.setMessage("GPS not On");
builder1.setCancelable(true);
builder1.setPositiveButton("Enable GPS",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
MainActivity.this.startActivity(intent);
dialog.dismiss();
}
});
builder1.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
alert11 = builder1.create();
alert11.show();
}
}