ventanas servicio respuesta responder que escritorio dejo degradó administrador android

android - servicio - Vista no conectada al bloqueo del administrador de ventanas



servicio aero windows 7 (13)

Anula el Destrucción de la Actividad y Descarta tu Diálogo y hazlo nulo

protected void onDestroy () { if(mProgressDialog != null) if(mProgressDialog.isShowing()) mProgressDialog.dismiss(); mProgressDialog= null; }

Estoy usando ACRA para informar bloqueos de aplicaciones. pDialog.dismiss(); mensaje de error View not attached to window manager 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 bloqueos del View not attached to window manager que recibo, pero sigo recibiendo algunas y no estoy seguro de cómo resolverlas.

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 estoy perdiendo para evitar que ocurra este accidente?


Basado en @erakitin answer, pero también compatible para las versiones de Android <API level 17. Tristemente Activity.isDestroyed() solo es compatible desde el nivel 17 de la API, por lo que si estás segmentando un nivel de API anterior como yo, tendrás que compruébalo tú mismo. Después de eso, no obtuve la View not attached to window manager excepción del View not attached to window manager .

Código de ejemplo

public class MainActivity extends Activity { private TestAsyncTask mAsyncTask; private ProgressDialog mProgressDialog; private boolean mIsDestroyed; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (condition) { mAsyncTask = new TestAsyncTask(); mAsyncTask.execute(); } } @Override protected void onResume() { super.onResume(); if (mAsyncTask != null && mAsyncTask.getStatus() != AsyncTask.Status.FINISHED) { Toast.makeText(this, "Still loading", Toast.LENGTH_LONG).show(); return; } } @Override protected void onDestroy() { super.onDestroy(); mIsDestroyed = true; if (mProgressDialog != null && mProgressDialog.isShowing()) { mProgressDialog.dismiss(); } } public class TestAsyncTask extends AsyncTask<Void, Void, AsyncResult> { @Override protected void onPreExecute() { super.onPreExecute(); mProgressDialog = ProgressDialog.show(MainActivity.this, "Please wait", "doing stuff.."); } @Override protected AsyncResult doInBackground(Void... arg0) { // Do long running background stuff return null; } @Override protected void onPostExecute(AsyncResult result) { // Use MainActivity.this.isDestroyed() when targeting API level 17 or higher if (mIsDestroyed)// Activity not there anymore return; mProgressDialog.dismiss(); // Handle rest onPostExecute } } }


El problema podría ser que la Activity haya finished o esté en progress of finishing .

Agregar un cheque es isFinishing y descartar el diálogo solo cuando esto es false

if (!YourActivity.this.isFinishing() && pDialog != null) { pDialog.dismiss(); }

isFinishing: compruebe si esta actividad está en proceso de finalización, ya sea porque llamó para finish o porque alguien más la solicitó.


En primer lugar, el motivo del bloqueo es que el índice de decorView es -1, podemos conocerlo desde el código fuente de Android, hay un fragmento de código:

clase: android.view.WindowManagerGlobal

archivo: WindowManagerGlobal.java

private int findViewLocked(View view, boolean required) { final int index = mViews.indexOf(view); //here, view is decorView,comment by OF if (required && index < 0) { throw new IllegalArgumentException("View=" + view + " not attached to window manager"); } return index; }

así que obtenemos la resolución de seguimiento, solo juzgue el índice de decorView, si es más que 0, luego continúe o simplemente devuelva y desista, deséchelo de la siguiente manera:

try { Class<?> windowMgrGloable = Class.forName("android.view.WindowManagerGlobal"); try { Method mtdGetIntance = windowMgrGloable.getDeclaredMethod("getInstance"); mtdGetIntance.setAccessible(true); try { Object windownGlobal = mtdGetIntance.invoke(null,null); try { Field mViewField = windowMgrGloable.getDeclaredField("mViews"); mViewField.setAccessible(true); ArrayList<View> mViews = (ArrayList<View>) mViewField.get(windownGlobal); int decorViewIndex = mViews.indexOf(pd.getWindow().getDecorView()); Log.i(TAG,"check index:"+decorViewIndex); if (decorViewIndex < 0) { return; } } catch (NoSuchFieldException e) { e.printStackTrace(); } } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } catch (NoSuchMethodException e) { e.printStackTrace(); } } catch (ClassNotFoundException e) { e.printStackTrace(); } if (pd.isShowing()) { pd.dismiss(); }


Este problema se debe a que su actividad finaliza antes de que se llame a la función de descartar. Maneje la excepción y verifique su registro ADB por el motivo exacto.

/** * After completing background task Dismiss the progress dialog * **/ protected void onPostExecute(String file_url) { try { if (pDialog!=null) { pDialog.dismiss(); //This is line 624! } } catch (Exception e) { // do nothing } something(note); }


Para el Dialog creado en un Fragment , utilizo el siguiente código:

ProgressDialog myDialog = new ProgressDialog(getActivity()); myDialog.setOwnerActivity(getActivity()); ... Activity activity = myDialog.getOwnerActivity(); if( activity!=null && !activity.isFinishing()) { myDialog.dismiss(); }

Uso este patrón para tratar el caso cuando un Fragment puede ser separado de la Activity .


Puede ser que inicialice pDialog globalmente, luego quítelo e inicialice su vista o diálogo localmente. Tengo el mismo problema, lo he hecho y mi problema se ha resuelto. Espero que funcione para ti.


Reemplazar aConfigurationChanged y descartar el diálogo de progreso. Si el diálogo de progreso se crea en vertical y se descarta en el paisaje, arrojará la vista no asociada al error del administrador de ventanas.

Además, detenga la barra de progreso y detenga la tarea asincrónica en los métodos onPause (), onBackPressed y onDestroy.

if(asyncTaskObj !=null && asyncTaskObj.getStatus().equals(AsyncTask.Status.RUNNING)){ asyncTaskObj.cancel(true); }


Tengo una forma de reproducir esta excepción.

Yo uso 2 AsyncTask . Una tarea larga y otra una tarea corta. Después de completar la tarea corta, llame a finish() . Cuando la tarea larga se completa y llama a Dialog.dismiss() , se bloquea.

Aquí está mi código de muestra:

public class MainActivity extends Activity { private static final String TAG = "MainActivity"; private ProgressDialog mProgressDialog; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.d(TAG, "onCreate"); new AsyncTask<Void, Void, Void>(){ @Override protected void onPreExecute() { mProgressDialog = ProgressDialog.show(MainActivity.this, "", "plz wait...", true); } @Override protected Void doInBackground(Void... nothing) { try { Log.d(TAG, "long thread doInBackground"); Thread.sleep(20000); } catch (InterruptedException e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(Void result) { Log.d(TAG, "long thread onPostExecute"); if (mProgressDialog != null && mProgressDialog.isShowing()) { mProgressDialog.dismiss(); mProgressDialog = null; } Log.d(TAG, "long thread onPostExecute call dismiss"); } }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); new AsyncTask<Void, Void, Void>(){ @Override protected Void doInBackground(Void... params) { try { Log.d(TAG, "short thread doInBackground"); Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(Void aVoid) { super.onPostExecute(aVoid); Log.d(TAG, "short thread onPostExecute"); finish(); Log.d(TAG, "short thread onPostExecute call finish"); } }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } @Override protected void onDestroy() { super.onDestroy(); Log.d(TAG, "onDestroy"); } }

Puedes probar esto y descubrir cuál es la mejor manera de solucionar este problema. De mi estudio, hay al menos 4 formas de solucionarlo:

  1. @ erakitin''s answer: call isFinishing() para verificar el estado de la actividad
  2. @ Respuesta de Kapé: establecer bandera para verificar el estado de la actividad
  3. Use try / catch para manejarlo.
  4. Llame a AsyncTask.cancel(false) en onDestroy() . Evitará que la asynctask se ejecute en onPostExecute() pero ejecute onCancelled() lugar.
    Nota: onPostExecute() se ejecutará incluso si llama a AsyncTask.cancel(false) en el sistema operativo Android anterior, como Android 2.XX

Puedes elegir el mejor para ti.


Vea cómo funciona el código aquí:

Después de llamar a la tarea Async, la tarea asíncrona se ejecuta en segundo plano. eso es deseable Ahora esta tarea Async tiene un diálogo de progreso que se adjunta a la Actividad, si le preguntas cómo, mira el código:

pDialog = new ProgressDialog(CLASS.this);

Estás pasando la Class.this es un contexto del argumento. Por lo tanto, el cuadro de diálogo Progreso aún está adjunto a la actividad.

Ahora considere el escenario: si tratamos de terminar la actividad usando el método finish (), mientras la tarea asincrónica está en progreso, es el punto donde intenta acceder al Recurso adjunto a la actividad, es decir, la progess bar cuando la actividad no es más allí.

Por lo tanto, obtienes:

java.lang.IllegalArgumentException: View not attached to window manager

.

Solución a esto:

1) Asegúrese de que el cuadro de diálogo se cierre o se cancele antes de que la actividad finalice.

2) Finalice la actividad, solo después de cerrar el cuadro de diálogo, que es la tarea asíncrona terminada.


mejor solución. El primer contexto de la consulta es el contexto de la actividad o el contexto de la aplicación si el contexto de la actividad solo comprueba si la actividad finalizó o no, entonces llama a dialog.show() o dialog.dismiss();

Vea el código de muestra a continuación ... ¡espero que sea útil!

Mostrar diálogo

if (context instanceof Activity) { if (!((Activity) context).isFinishing()) dialog.show(); }

Descartar el diálogo

if (context instanceof Activity) { if (!((Activity) context).isFinishing()) dialog.dismiss(); }

Si desea agregar más controles, agregue dialog.isShowing() o dialog !-null usando && condition.


Cómo reproducir el error:

  1. Habilite esta opción en su dispositivo: Settings -> Developer Options -> Don''t keep Activities .
  2. Presione el botón de Inicio mientras se está ejecutando AsyncTask y se muestra ProgressDialog .

El sistema operativo Android destruirá una actividad tan pronto como esté oculta. Cuando se llama a onPostExecute la Activity estará en estado de "finalización" y ProgressDialog no se adjuntará a la Activity .

Como arreglarlo:

  1. Compruebe el estado de la actividad en su método onPostExecute .
  2. Descartar el ProgressDialog en el método onDestroy . De lo contrario, se lanzará la excepción android.view.WindowLeaked . Esta excepción generalmente proviene de diálogos que aún están activos cuando la actividad está finalizando.

Prueba este código fijo:

public class YourActivity extends Activity { <...> private void showProgressDialog() { if (pDialog == null) { pDialog = new ProgressDialog(StartActivity.this); pDialog.setMessage("Loading. Please wait..."); pDialog.setIndeterminate(false); pDialog.setCancelable(false); } pDialog.show(); } private void dismissProgressDialog() { if (pDialog != null && pDialog.isShowing()) { pDialog.dismiss(); } } @Override protected void onDestroy() { dismissProgressDialog(); super.onDestroy(); } class LoadAllProducts extends AsyncTask<String, String, String> { /** * Before starting background thread Show Progress Dialog * */ @Override protected void onPreExecute() { showProgressDialog(); } /** * getting All products from url * */ protected String doInBackground(String... args) { doMoreStuff("internet"); return null; } /** * After completing background task Dismiss the progress dialog * **/ protected void onPostExecute(String file_url) { if (YourActivity.this.isDestroyed()) { // or call isFinishing() if min sdk version < 17 return; } dismissProgressDialog(); something(note); } } }


@Override public void onPause() { super.onPause(); if(pDialog != null) pDialog .dismiss(); pDialog = null; }

referir this