what libreria leaks last context android memory-leaks dialog

android - libreria - La actividad ha filtrado la ventana que se agregó originalmente



libreria leakcanary android (30)

¿Qué es este error, y por qué sucede?

05-17 18:24:57.069: ERROR/WindowManager(18850): Activity com.mypkg.myP has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44c46ff0 that was originally added here 05-17 18:24:57.069: ERROR/WindowManager(18850): android.view.WindowLeaked: Activity ccom.mypkg.myP has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44c46ff0 that was originally added here 05-17 18:24:57.069: ERROR/WindowManager(18850): at android.view.ViewRoot.<init>(ViewRoot.java:231) 05-17 18:24:57.069: ERROR/WindowManager(18850): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148) 05-17 18:24:57.069: ERROR/WindowManager(18850): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91) 05-17 18:24:57.069: ERROR/WindowManager(18850): at android.view.Window$LocalWindowManager.addView(Window.java:424) 05-17 18:24:57.069: ERROR/WindowManager(18850): at android.app.Dialog.show(Dialog.java:239) 05-17 18:24:57.069: ERROR/WindowManager(18850): at com.mypkg.myP$PreparePairingLinkageData.onPreExecute(viewP.java:183) 05-17 18:24:57.069: ERROR/WindowManager(18850): at android.os.AsyncTask.execute(AsyncTask.java:391) 05-17 18:24:57.069: ERROR/WindowManager(18850): at com.mypkg.myP.onCreate(viewP.java:94) 05-17 18:24:57.069: ERROR/WindowManager(18850): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 05-17 18:24:57.069: ERROR/WindowManager(18850): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2544) 05-17 18:24:57.069: ERROR/WindowManager(18850): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2621) 05-17 18:24:57.069: ERROR/WindowManager(18850): at android.app.ActivityThread.access$2200(ActivityThread.java:126) 05-17 18:24:57.069: ERROR/WindowManager(18850): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1932) 05-17 18:24:57.069: ERROR/WindowManager(18850): at android.os.Handler.dispatchMessage(Handler.java:99) 05-17 18:24:57.069: ERROR/WindowManager(18850): at android.os.Looper.loop(Looper.java:123) 05-17 18:24:57.069: ERROR/WindowManager(18850): at android.app.ActivityThread.main(ActivityThread.java:4595) 05-17 18:24:57.069: ERROR/WindowManager(18850): at java.lang.reflect.Method.invokeNative(Native Method) 05-17 18:24:57.069: ERROR/WindowManager(18850): at java.lang.reflect.Method.invoke(Method.java:521) 05-17 18:24:57.069: ERROR/WindowManager(18850): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) 05-17 18:24:57.069: ERROR/WindowManager(18850): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 05-17 18:24:57.069: ERROR/WindowManager(18850): at dalvik.system.NativeStart.main(Native Method)


Descartar el diálogo cuando la actividad se destruye.

@Override protected void onDestroy() { super.onDestroy(); if (pDialog!=null && pDialog.isShowing()){ pDialog.dismiss(); } }


Desencadené este error llamando erróneamente a hide() lugar de a un AlertDialog dismiss() en un AlertDialog .


El problema de acuerdo con mí es que está intentando llamar a un diálogo justo después de que se termina una actividad, por lo que, de acuerdo con lo que puede hacer, es demorar un poco al usar Handler y su problema se resolverá, por ejemplo:

Handler handler=new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { dialog.show(); //or dialog.dismiss(); } },100);


En mi caso, la razón fue que olvidé incluir un permiso en el archivo de manifiesto de Android.

¿Cómo me enteré? Bueno, al igual que @Bobby dice en un comentario debajo de la respuesta aceptada, simplemente desplácese hasta sus registros y verá la primera razón o evento que realmente lanzó la Excepción. Aparentemente, el mensaje "La actividad ha filtrado la ventana que se agregó originalmente" es solo una excepción que resultó de lo que sea la primera excepción.


Está intentando mostrar un diálogo después de salir de una actividad.

[EDITAR]

Esta pregunta es una de las principales búsquedas en Google para desarrolladores de Android, por lo tanto, agrega algunos puntos importantes de los comentarios, lo que podría ser más útil para futuros investigadores sin profundizar en la conversación de comentarios.

Respuesta 1 :

Está intentando mostrar un diálogo después de salir de una actividad.

Respuesta 2

Este error puede ser un poco engañoso en algunas circunstancias (aunque la respuesta sigue siendo completamente precisa), es decir, en mi caso se lanzó una Excepción no manejada en una AsyncTask, lo que provocó el cierre de la Actividad, luego un diálogo abierto de progreso provocó esta Excepción ... así que La excepción ''real'' fue un poco antes en el registro

Respuesta 3

La llamada despide () en la instancia de Diálogo que creó antes de salir de su actividad, por ejemplo, en onPause () o onDestroy ()


Esta no es la respuesta a la pregunta, pero es relevante para el tema.

Si la actividad ha definido un atributo en el Manifiesto.

android:noHistory="true"

luego, después de ejecutar onPause (), el contexto de la actividad se pierde. Entonces, todas las vistas que usan este contexto pueden dar este error.


Estaba obteniendo estos registros en mi aplicación de reproductor de video. Estos mensajes fueron lanzados mientras el reproductor de video estaba cerrado. Curiosamente, solía obtener estos registros una vez en algunas ejecuciones de manera aleatoria. También mi aplicación no involucra en ningún progressdialog . Finalmente, resolví este problema con la siguiente implementación.

@Override protected void onPause() { Log.v("MediaVideo", "onPause"); super.onPause(); this.mVideoView.pause(); this.mVideoView.setVisibility(View.GONE); } @Override protected void onDestroy() { Log.v("MediaVideo", "onDestroy"); super.onDestroy(); } @Override protected void onResume() { Log.v("MediaVideo", "onResume"); super.onResume(); this.mVideoView.resume(); }

OnPause el OnPause con la llamada a mVideoView.pause() y el conjunto de visibility a GONE . De esta manera podría resolver el problema de error de registro "La Activity has leaked window ".


Estaba teniendo el mismo problema y encontré esta página, y aunque mi situación era diferente, llamé a finish desde un bloque if antes de que definiera el cuadro de alerta.

Por lo tanto, simplemente llamar a dismiss no funcionaría (ya que aún no se ha hecho), pero después de leer la respuesta de Alex Volovoy y darme cuenta de que era el cuadro de alerta que lo causaba. Intenté agregar una declaración de devolución justo después de finalizar dentro de ese bloque if y que solucionó el problema.

Pensé que una vez que llamabas a terminar, paraba todo y terminaba justo allí, pero no lo hace. Parece que va al final del bloque de código en el que está y luego termina.

Por lo tanto, si desea implementar una situación en la que a veces termine antes de hacer algún código, debe poner una declaración de devolución inmediatamente después de la finalización o continuará y actuará como si se hubiera llamado la finalización al final de la Bloque de código no donde lo llamaste. Es por eso que estaba recibiendo todos esos errores extraños.

private picked(File aDirectory){ if(aDirectory.length()==0){ setResult(RESULT_CANCELED, new Intent()); finish(); return; } AlertDialog.Builder alert= new AlertDialog.Builder(this); // Start dialog builder alert .setTitle("Question") .setMessage("Do you want to open that file?"+aDirectory.getName()); alert .setPositiveButton("OK", okButtonListener) .setNegativeButton("Cancel", cancelButtonListener); alert.show(); }

Si no pones la devolución justo después de que haya llamado a finalizar, actuará como si la hubieras llamado después de alert.show(); y, por lo tanto, diría que la ventana se filtra al finalizar justo después de hacer aparecer el diálogo, aunque ese no sea el caso, aún así lo cree.

Pensé que agregaría esto como aquí, ya que muestra que el comando de finalización actuó de manera diferente a como lo hice y supongo que hay otras personas que piensan lo mismo que yo antes de que descubriera esto.


Este problema surge cuando se intenta mostrar un diálogo después de haber salido de una actividad.

Acabo de resolver este problema simplemente escribiendo el siguiente código:

@Override public void onDestroy(){ super.onDestroy(); if ( progressDialog!=null && progressDialog.isShowing() ){ progressDialog.cancel(); } }

Básicamente, desde la clase en la que inició progressDialog, anule el método onDestroy y haga esto. Se solucionó el problema de "La actividad se ha filtrado".


Esto me sucedió cuando uso ProgressDialog en AsyncTask . Actualmente estoy usando el método hide() en onPostExecute . Basándome en la respuesta de @Alex Volovoy, necesito usar la función de dismiss() con ProgressDialog para eliminarlo en onPostExecute y listo.

progressDialog.hide(); // Don''t use it, it gives error progressDialog.dismiss(); // Use it


Esto podría ayudar.

if (! isFinishing()) { dialog.show(); }


Esto puede ser si tiene un error en la función doInBackground() y tiene este código.

Trate de agregar el diálogo por fin. Al principio verifique y arregle la función doInBackground()

protected void onPreExecute() { super.onPreExecute(); pDialog = new ProgressDialog(CreateAccount.this); pDialog.setMessage("Creating Product.."); pDialog.setIndeterminate(false); pDialog.setCancelable(true); pDialog.show(); } protected String doInBackground(String...args) { ERROR CAN BE IS HERE } protected void onPostExecute(String file_url) { // dismiss the dialog once done pDialog.dismiss();


Generalmente, este problema se produce debido al cuadro de diálogo de progreso: puede resolverlo utilizando cualquiera de los siguientes métodos en su actividad:

// 1): @Override protected void onPause() { super.onPause(); if ( yourProgressDialog!=null && yourProgressDialog.isShowing() ) { yourProgressDialog.cancel(); } } // 2) : @Override protected void onDestroy() { super.onDestroy(); if ( yourProgressDialog!=null && yourProgressDialog.isShowing() { yourProgressDialog.cancel(); } }


La mejor solución es poner esto antes de mostrar progressbar o progressDialog

if (getApplicationContext().getWindow().getDecorView().isShown()) { //Show Your Progress Dialog }


La solución es llamar a dismiss() en el Dialog que creó en viewP.java:183 antes de salir de la Activity , por ejemplo, en onPause() . Todas las Window y Dialog deben estar cerradas antes de abandonar una Activity .


Las excepciones de ventana filtrada tienen dos razones:

1) muestra el cuadro de diálogo cuando no existe el Contexto de actividad, para resolverlo, debe mostrar el cuadro de diálogo solo si está seguro de que existe la Actividad:

if(getActivity()!= null && !getActivity().isFinishing()){ Dialog.show(); }

2) No descartar adecuadamente el diálogo, para resolverlo use este código:

@Override public void onDestroy(){ super.onDestroy(); if ( Dialog!=null && Dialog.isShowing() ){ Dialog.dismiss(); } }


Las respuestas a esta pregunta fueron todas correctas, pero un poco confusas para que yo realmente entendiera por qué. Después de jugar alrededor de 2 horas, la razón de este error (en mi caso) me golpeó:

Ya sabes, por leer otras respuestas, que el error X has leaked window DecorView@d9e6131[] significa que se abrió un cuadro de diálogo cuando se cerró la aplicación. ¿Pero por qué?

Puede ser que su aplicación se bloquee por alguna otra razón mientras el diálogo estaba abierto.

Esto provocó que su aplicación se cerrara debido a algún error en su código, lo que llevó a que el cuadro de diálogo permanezca abierto al mismo tiempo que su aplicación se cerró debido al otro error.

Entonces, mira a través de tu lógica. Resuelve el primer error, y luego el segundo error se resolverá solo.

Un error causa otro, lo que causa otro, como DOMINOS!


No solo intente mostrar una alerta, sino que también puede invocarse cuando finaliza una instancia particular de actividad e intenta iniciar una nueva actividad / servicio o intenta detenerla.

Ejemplo:

OldActivity instance; oncreate() { instance=this; } instance.finish(); instance.startActivity(new Intent(ACTION_MAIN).setClass(instance, NewActivity.class));


Prueba este código:

public class Sample extends Activity(){ @Override public void onCreate(Bundle instance){ } @Override public void onStop() { super.onStop(); progressdialog.dismiss(); // try this } }


Pruebe el siguiente código, funcionará cada vez que descartará el diálogo de progreso y verá si su instancia está disponible o no.

try { if (null != progressDialog && progressDialog.isShowing()) { progressDialog.dismiss(); progressDialog = null; } } catch (Exception e) { e.printStackTrace(); }


Puede obtener esta excepción solo por un error simple / tonto, (por ejemplo) llamando accidentalmente a finish() después de haber mostrado un AlertDialog , si pierde una declaración de interrupción de llamada en una declaración de cambio ...

@Override public void onClick(View v) { switch (v.getId()) { case R.id.new_button: openMyAlertDialog(); break; <-- If you forget this the finish() method below will be called while the dialog is showing! case R.id.exit_button: finish(); break; } }

El método finish() cerrará la Activity , ¡pero el AlertDialog todavía se muestra!

Por lo tanto, cuando esté mirando fijamente el código, en busca de problemas de subprocesos incorrectos o codificación compleja, no pierda de vista el bosque por los árboles. A veces puede ser simplemente algo tan simple y tonto como una declaración de ruptura faltante. :)


Recientemente me enfrenté al mismo problema.

La razón detrás de este problema es que la actividad se cierra antes de que se cierre el diálogo. Hay varias razones para que suceda lo anterior. Los mencionados en los posts anteriores también son correctos.

Me metí en una situación, porque en el hilo, estaba llamando a una función que estaba lanzando una excepción. Debido a que la ventana estaba siendo descartada y por lo tanto la excepción.


Se produce el error "La Activity has leaked window that was originally added... " cuando intenta mostrar una alerta después de que la Activity haya finished efectivamente.

Tienes dos opciones AFAIK:

  1. Vuelva a pensar en el inicio de sesión de su alerta: llame a dismiss() en el dialog antes de salir de su actividad.
  2. Coloque el dialog de dialog en un hilo diferente y ejecútelo en ese thread (independientemente de la activity actual).

Si está utilizando AsyncTask , probablemente ese mensaje de registro puede ser engañoso. Si busca en su registro, puede encontrar otro error, probablemente uno en su método doInBackground() de su AsyncTask , que está haciendo que su Activity actual AsyncTask , y así una vez que AsyncTask regrese ... bueno, ya sabe. descanso. Algunos otros usuarios ya explicaron eso aquí :-)


Solo asegúrese de que su actividad no se cierre inesperadamente debido a algunas excepciones generadas en algún lugar de su código. Generalmente ocurre en una tarea asíncrona cuando la actividad se enfrenta a un cierre forzado en el método doinBackground y luego asynctask vuelve al método onPostexecute.


Tenía el mismo mensaje de error oscuro y no tenía idea de por qué. Dadas las pistas de las respuestas anteriores, cambié mis llamadas que no eran de GUI a mDialog.finish () para que fueran mDialog.dismiss () y los errores desaparecieron. Esto no estaba afectando el comportamiento de mi widget, pero era desconcertante y bien podría haber estado marcando una pérdida de memoria importante.


Tenía el problema donde terminé una actividad cuando todavía se mostraba un ProgressDialog.

Así que primero oculta el diálogo y luego termina la actividad.


onPreExecute crear Progressdialog objeto Progressdialog en el método AsyncTask de AsyncTask y dismiss en el método onPostExecute .


La mejor solución es simplemente agregar el cuadro de diálogo en el cuadro de prueba probar y descartar cuando ocurre una excepción

Solo usa el código de abajo

try { dialog.show(); } catch (Exception e) { dialog.dismiss(); }


if (mActivity != null && !mActivity.isFinishing() && mProgressDialog != null && mProgressDialog.isShowing()) { mProgressDialog.dismiss(); }