studio movil log depurar debuggear debug chrome aplicacion android service view stack-trace

android - movil - No puedo encontrar la causa de mi accidente con este rastro de pila



depurar aplicacion android en movil (5)

Lo que hace mi aplicación es mostrar una vista de superposición del sistema adjunta a través de windowManager.addView() y WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY windowManager.addView() . Esto se hace con un Servicio, que administra la visibilidad de la vista y algunas otras cosas.

Sin embargo, estoy recibiendo informes de fallos y no puedo reproducirlos. Además, el seguimiento de la pila de bloqueo no tiene nada que ver con el paquete de mi aplicación, así que realmente no puedo entender el origen de este problema. Los siguientes son dos stacktraces que provienen de diferentes fuentes, pero parecen estar relacionados:

java.lang.NullPointerException: Attempt to invoke virtual method ''void android.view.View.measure(int, int)'' on a null object reference at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2388) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2101) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1297) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7011) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:777) at android.view.Choreographer.doCallbacks(Choreographer.java:590) at android.view.Choreographer.doFrame(Choreographer.java:560) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:763) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:145) at android.app.ActivityThread.main(ActivityThread.java:6938) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)

.

java.lang.NullPointerException: Attempt to invoke virtual method ''int android.view.View.getMeasuredWidth()'' on a null object reference at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2484) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2181) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1293) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6599) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:800) at android.view.Choreographer.doCallbacks(Choreographer.java:603) at android.view.Choreographer.doFrame(Choreographer.java:572) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:786) at android.os.Handler.handleCallback(Handler.java:815) at android.os.Handler.dispatchMessage(Handler.java:104) at android.os.Looper.loop(Looper.java:194) at android.app.ActivityThread.main(ActivityThread.java:5616) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:959) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:754)

Parece que el SO (ViewRootImpl) está causando este problema porque posee una referencia nula a mi vista. Entonces no puedo encontrar una solución para esto.

Parece suceder en todas las versiones de Android desde 4.4 y mi aplicación está protegida. Estos seguimientos de pila se obtienen de los informes de fallos de Google Play Store

Aquí es cómo adjunto vista a la ventana del sistema como una superposición:

private void attachToSystemWindows(boolean overlayNavigationBar) { final WindowManager windowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); final DisplayMetrics metrics = new DisplayMetrics(); windowManager.getDefaultDisplay().getMetrics(metrics); final boolean isNavBarInBottom = isNavBarInBottom(); final WindowManager.LayoutParams params = new WindowManager.LayoutParams( calculateWindowWidth(overlayNavigationBar, isNavBarInBottom, metrics, mNavigationBarHeight), calculateWindowHeight(overlayNavigationBar, isNavBarInBottom, metrics, mNavigationBarHeight), 0, 0, WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, 0x50728, -3 ); params.gravity = Gravity.TOP; windowManager.addView(this, params); } private boolean isNavBarInBottom() { final boolean isLargeDevice = getResources().getConfiguration().smallestScreenWidthDp >= 600; final int orientation = getResources().getConfiguration().orientation; if (BuildConfig.DEBUG) Log.d("MeshView", "Is NavBar in bottom: " + (isLargeDevice || orientation == Configuration.ORIENTATION_PORTRAIT)); return isLargeDevice || orientation == Configuration.ORIENTATION_PORTRAIT; }

Y mi método onMeasure:

@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (BuildConfig.DEBUG) Log.d("MeshView", "OnMeasure"); setMeasuredDimension( Math.max(getSuggestedMinimumWidth(), resolveSize(SIZE_MIN_WIDTH, widthMeasureSpec)), Math.max(getSuggestedMinimumHeight(), resolveSize(SIZE_MIN_HEIGHT, heightMeasureSpec)) ); }


Proguard puede causar un problema de Stack Trace, aunque debería haber un indicio de tu propio código, aunque es necesario descifrar su lectura, así que esto me detiene, desactiva Proguard a través de Gradle, luego ejecuta de nuevo y ves.


Creo que no está pasando la bandera correcta al crear params .

final WindowManager.LayoutParams params = new WindowManager.LayoutParams( calculateWindowWidth(overlayNavigationBar, isNavBarInBottom, metrics, mNavigationBarHeight), calculateWindowHeight(overlayNavigationBar, isNavBarInBottom, metrics, mNavigationBarHeight), 0, 0, WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, 0x50728, // problem might be here. -3 );

Debería ser uno de estos valores .

Así que utilízalo de la siguiente manera (evita pasar directamente los valores hexadecimales):

final WindowManager.LayoutParams params = new WindowManager.LayoutParams( calculateWindowWidth(overlayNavigationBar, isNavBarInBottom, metrics, mNavigationBarHeight), calculateWindowHeight(overlayNavigationBar, isNavBarInBottom, metrics, mNavigationBarHeight), 0, 0, WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON, //any flag PixelFormat.TRANSLUCENT );

También he hecho referencia a PixelFormat .

Intenta cambiar así y mira si eso funciona.


Tuve el mismo problema en mi aplicación. Resolví el problema usando

public static final int TYPE_SYSTEM_ALERT;

en lugar de TYPE_SYSTEM_OVERLAY. Supongo que la vista ya está destruida antes de invocar onMeasure (). Este tipo de superposición de alguna manera crea un problema especialmente en los dispositivos pre kat con nombre.

Nota: si desea que su ventana de superposición se muestre detrás de la barra de estado y aún por encima de todas las otras aplicaciones, use;

public static final int TYPE_PHONE;

Espero que esto ayude.


es corto cuando quita la vista mediante ( windowManager.removeView(this) ) después de una cadena de llamadas ViewRoot.dispatchDetachedFromWindow () que esencialmente establece la vista del viewroot en nulo, razón por la cual tiene el NPE en el cruce.

En detalles: haciendo

windowManager.removeView(this);

En esencia, se llama a morir en el ViewRoot de la vista, que luego envía MSG_DIE a su manejador para que mata más adelante cuando es seguro y agrega la vista a la lista mDyingViews en WindowManagerGlobal. esto está todo bien,

sin embargo, al llamar:

windowManager.addView(this, layoutParams);

fuerza la muerte de ViewRoot y llama a doDie() y consecutivamente a ViewRoot.dispatchDetachedFromWindow() que establece que la vista se ViewRoot.dispatchDetachedFromWindow() mientras está atravesando y tiene NPE.

para obtener más información, consulte WindowManagerGlobal y ViewRootImpl


Asombroso. Finalmente encontré la raíz de mi problema, pero no el motivo ... Estaba haciendo algo con mi punto de vista: quería cambiar sus parámetros de diseño según su orientación, por lo que onConfigurationChanged() .

Luego utilicé una manera desagradable de actualizar los parámetros de diseño: separar y luego adjuntarlo de nuevo a WindowManager , como este:

@Override protected void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); final ViewGroup.LayoutParams layoutParams = getLayoutParams(); if (!(layoutParams instanceof WindowManager.LayoutParams)) return; //Fix for some ClassCastException in Samsung devices final WindowManager windowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); final DisplayMetrics metrics = new DisplayMetrics(); windowManager.getDefaultDisplay().getMetrics(metrics); final boolean isNavBarInBottom = isNavBarInBottom(); layoutParams.width = calculateWindowWidth(mOverlayNavigationBar, isNavBarInBottom, metrics, mNavigationBarHeight); layoutParams.height = calculateWindowHeight(mOverlayNavigationBar, isNavBarInBottom, metrics, mNavigationBarHeight); windowManager.removeView(this); windowManager.addView(this, layoutParams); }

Supongo que sucede algo malo en la clase ViewRootImpl , lo que provoca que no se maneje correctamente la ViewRootImpl , lo que provoca un error.

Para solucionar esto, simplemente debe seguir el camino correcto: use WindowManager.updateViewLayout(); método:

@Override protected void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); if (BuildConfig.DEBUG) Log.d("MeshView", "OnConfigurationChanged"); final ViewGroup.LayoutParams layoutParams = getLayoutParams(); if (!(layoutParams instanceof WindowManager.LayoutParams)) return; //Fix for some ClassCastException in Samsung devices final WindowManager windowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); final DisplayMetrics metrics = new DisplayMetrics(); windowManager.getDefaultDisplay().getMetrics(metrics); final boolean isNavBarInBottom = isNavBarInBottom(); layoutParams.width = calculateWindowWidth(mOverlayNavigationBar, isNavBarInBottom, metrics, mNavigationBarHeight); layoutParams.height = calculateWindowHeight(mOverlayNavigationBar, isNavBarInBottom, metrics, mNavigationBarHeight); //windowManager.removeView(this); DON''T DO THIS //windowManager.addView(this, layoutParams); DON''T DO THIS windowManager.updateViewLayout(this, layoutParams); //DO THIS INSTEAD }

Esto parece solucionar mi problema. Debo agradecer al autor de esta publicación, que me permitió encontrar esta solución): Android: cambiar LayoutParams of View agregado por WindowManager