Estoy usando ACRA para reportar bloqueos de aplicaciones. Estaba recibiendo un View not attached to window manager
mensaje de error y pensé que lo había solucionado envolviendo el pDialog.dismiss();
en una declaración if:
if (pDialog!=null)
{
if (pDialog.isShowing())
{
pDialog.dismiss();
}
}
Se ha reducido la cantidad de View not attached to window manager
accidentes que recibo, pero todavía estoy recibiendo algunos y no estoy seguro de cómo solucionarlo.
Mensaje de error:
java.lang.IllegalArgumentException: View not attached to window manager
at android.view.WindowManagerGlobal.findViewLocked(WindowManagerGlobal.java:425)
at android.view.WindowManagerGlobal.removeView(WindowManagerGlobal.java:327)
at android.view.WindowManagerImpl.removeView(WindowManagerImpl.java:83)
at android.app.Dialog.dismissDialog(Dialog.java:330)
at android.app.Dialog.dismiss(Dialog.java:312)
at com.package.class$LoadAllProducts.onPostExecute(class.java:624)
at com.package.class$LoadAllProducts.onPostExecute(class.java:1)
at android.os.AsyncTask.finish(AsyncTask.java:631)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:176)
at android.app.ActivityThread.main(ActivityThread.java:5419)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1046)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:862)
at dalvik.system.NativeStart.main(Native Method)
Fragmento de código:
class LoadAllProducts extends AsyncTask<String, String, String>
{
/**
* Before starting background thread Show Progress Dialog
* */
@Override
protected void onPreExecute()
{
super.onPreExecute();
pDialog = new ProgressDialog(CLASS.this);
pDialog.setMessage("Loading. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
/**
* getting All products from url
* */
protected String doInBackground(String... args)
{
// Building Parameters
doMoreStuff("internet");
return null;
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(String file_url)
{
// dismiss the dialog after getting all products
if (pDialog!=null)
{
if (pDialog.isShowing())
{
pDialog.dismiss(); //This is line 624!
}
}
something(note);
}
}
Manifiesto:
<activity
android:name="pagename.CLASS"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout"
android:label="@string/name" >
</activity>
¿Qué me falta para evitar que ocurra este bloqueo?
AsyncTask
se declara dentroActivity
oFragment
?Respuestas:
Cómo reproducir el error:
Settings -> Developer Options -> Don't keep Activities
.AsyncTask
se ejecuta yProgressDialog
se muestra.El sistema operativo Android destruirá una actividad tan pronto como esté oculta. Cuando
onPostExecute
se llamaActivity
, estará en estado de "finalización" yProgressDialog
no se adjuntaráActivity
.Como arreglarlo:
onPostExecute
método.ProgressDialog
inonDestroy
. De lo contrario, seandroid.view.WindowLeaked
lanzará una excepción. Esta excepción generalmente proviene de diálogos que aún están activos cuando la actividad está terminando.Prueba este código fijo:
fuente
isDestroyed()
másisFinishing()
en todas las API para este propósito específico?isFinishing()
no se garantiza que seatrue
si la actividad es destruida por el sistema, consulte la documentación sobre Actividades .// or call isFinishing() if min sdk version < 17
, se encuentra con la misma excepción. Por lo tanto, necesitamos una solución diferente a esta respuesta para aplicaciones que se ejecutan en API <17.myActivityWeakReference.get() != null && !myActivityWeakReference.get().isFinishing()
El problema podría ser que
Activity
han estadofinished
o enprogress of finishing
.Agregue un cheque
isFinishing
y descarte el diálogo solo cuando esto seafalse
isFinishing: verifique si esta actividad está en proceso de finalización, ya sea porque lo solicitó
finish
o si alguien más ha solicitado que finalice.fuente
Para
Dialog
creado en aFragment
, uso el siguiente código:Utilizo este patrón para tratar el caso cuando un
Fragment
puede ser separado delActivity
.fuente
Vea cómo funciona el Código aquí:
Después de llamar a la tarea asincrónica, la tarea asincrónica se ejecuta en segundo plano. Eso es deseable. Ahora, esta tarea Async tiene un cuadro de diálogo de progreso que se adjunta a la Actividad, si pregunta cómo ver el código:
Estás pasando el
Class.this
contexto como al argumento. Por lo tanto, el cuadro de diálogo Progreso todavía está adjunto a la actividad.Ahora considere el escenario: si intentamos finalizar la actividad utilizando el método finish (), mientras la tarea asíncrona está en progreso, es el punto donde está intentando acceder al Recurso adjunto a la actividad, es decir, el
progress bar
cuando la actividad ya no está ahí.Por lo tanto, obtienes:
Solución a esto:
1) Asegúrese de que el cuadro de diálogo se descarta o cancela antes de que finalice la actividad.
2) Finalice la actividad, solo después de cerrar el cuadro de diálogo, es decir, la tarea asincrónica ha terminado.
fuente
Activity
; Android puede terminarlo en cualquier momento. Entonces, el # 2 no tiene sentido.Basado en la respuesta @erakitin, pero también es compatible con las versiones de Android <nivel API 17. Lamentablemente, Activity.isDestroyed () solo es compatible desde el nivel API 17, por lo que si está apuntando a un nivel API más antiguo como yo, tendrá que compruébalo tú mismo. No tengo la
View not attached to window manager
excepción después de eso.Código de ejemplo
fuente
referir esto .
fuente
Anular onConfigurationChanged y descartar el diálogo de progreso. Si el diálogo de progreso se crea en vertical y se descarta en horizontal, arrojará el error Vista no adjunta al administrador de ventanas.
También detenga la barra de progreso y detenga la tarea asíncrona en los métodos onPause (), onBackPressed y onDestroy.
fuente
Anular onDestruir la actividad y descartar su diálogo y hacerlo nulo
fuente
En primer lugar, el motivo del bloqueo es que el índice de decorView es -1, podemos saberlo por el código fuente de Android, hay un fragmento de código:
así que obtenemos la resolución de seguimiento, solo juzgue el índice de decorView, si es más de 0, continúe o simplemente regrese y abandone el descarte, codifique de la siguiente manera:
fuente
Anule el
dismiss()
método como este:Para reproducir el problema, simplemente finalice la actividad antes de cerrar el cuadro de diálogo.
fuente
mejor solución. Verificar el primer contexto es el contexto de la actividad o el contexto de la aplicación si el contexto de la actividad solo verifica que la actividad haya finalizado o no, luego llame
dialog.show()
odialog.dismiss();
Si desea agregar más comprobaciones, agregue
dialog.isShowing()
odialog !-null
use la&&
condición.fuente
Este problema se debe a que su actividad finaliza antes de que se llame a la función de descarte. Maneje la excepción y verifique su registro ADB por la razón exacta.
fuente
Tengo una manera de reproducir esta excepción.
Yo uso 2
AsyncTask
. Uno hace una tarea larga y otro hace una tarea corta. Después de completar la tarea corta, llamefinish()
. Cuando se completa una tarea larga y se llamaDialog.dismiss()
, se bloquea.Aquí está mi código de muestra:
Puede probar esto y descubrir cuál es la mejor manera de solucionar este problema. De mi estudio, hay al menos 4 formas de solucionarlo:
isFinishing()
para verificar el estado de la actividadAsyncTask.cancel(false)
enonDestroy()
. Evitará que el asinctask se ejecute,onPostExecute()
pero se ejecutará en suonCancelled()
lugar.Nota:
onPostExecute()
aún se ejecutará incluso si llamasAsyncTask.cancel(false)
en un sistema operativo Android anterior, como Android 2.XXPuedes elegir el mejor para ti.
fuente
Puede ser que inicialice pDialog globalmente, luego elimínelo e inicialice su vista o diálogo localmente. Tengo el mismo problema, lo he hecho y mi problema está resuelto. Espero que funcione para ti.
fuente
también hemos descartado nuestro diálogo sobre
onPause
método oonDestroy
métodofuente