Android 4.4 KitKat accidente aleatorio

EDIT: Antes de votar a la baja e implicar cosas, por favor entienda que no puedo reproducir este error. Esto ocurre constantemente en ciertos dispositivos a los que no tengo acceso, pero no después de un restablecimiento de firmware.

Recientemente descubrí accidentes aleatorios en una aplicación que estoy desarrollando para un cliente. La aplicación tiene aproximadamente 100.000 usuarios activos ahora después de 3 años.

Hemos visto el accidente en Nexus 4 y 5, ambos con Android 4.4 KitKat.

No podemos reproducirlo en nuestro propio Nexus 4 y 5 en ejecución 4.4.

Hemos tenido un cliente a través de nuestro apoyo. Nos dijo que el accidente sucede cada vez en el mismo lugar cuando invocando una nueva actividad. Estaba dirigiendo a Dalvik, no a ART. Después de restablecer el firmware, la aplicación funcionó bien y no pudo reproducirla de nuevo.

No puedo publicar la fuente o el diseño por razones legales, pero tengo este stacktrace:

java.lang.RuntimeException: Unable to start activity ComponentInfo{xx.xxx.xxxxx.xxx.xxxxxx.prod/xx.xxx.xxxxx.xxx.PaymentsActivity}: java.lang.NullPointerException at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2176) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2226) at android.app.ActivityThread.access$700(ActivityThread.java:135) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1397) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4998) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:777) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:593) at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:126) at dalvik.system.NativeStart.main(Native Method) Caused by: java.lang.NullPointerException at android.view.View.sendAccessibilityEventUncheckedInternal(View.java:4938) at android.view.View.sendAccessibilityEventUnchecked(View.java:4919) at android.view.View$SendViewStateChangedAccessibilityEvent.run(View.java:19433) at android.view.View$SendViewStateChangedAccessibilityEvent.runOrPost(View.java:19465) at android.view.View.notifyViewAccessibilityStateChangedIfNeeded(View.java:7265) at android.view.View.setFlags(View.java:8990) at android.view.View.setVisibility(View.java:6020) at android.view.LayoutInflater.parseInclude(LayoutInflater.java:859) at de.robv.android.xposed.XposedBridge.invokeOriginalMethodNative(Native Method) at de.robv.android.xposed.XposedBridge.handleHookedMethod(XposedBridge.java:547) at android.view.LayoutInflater.parseInclude(Native Method) at android.view.LayoutInflater.rInflate(LayoutInflater.java:745) at android.view.LayoutInflater.inflate(LayoutInflater.java:492) at de.robv.android.xposed.XposedBridge.invokeOriginalMethodNative(Native Method) at de.robv.android.xposed.XposedBridge.handleHookedMethod(XposedBridge.java:547) at android.view.LayoutInflater.inflate(Native Method) at android.view.LayoutInflater.inflate(LayoutInflater.java:397) at android.view.LayoutInflater.inflate(LayoutInflater.java:353) at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:290) at android.app.Activity.setContentView(Activity.java:1928) at xx.xxx.xxxxx.xxx.StandardActivity.setContentView(StandardActivity.java:289) at xx.xxx.xxxxx.xxx.PaymentsActivity.onCreate(PaymentsActivity.java:61) at android.app.Activity.performCreate(Activity.java:5243) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2140) ... 12 more 

EDIT: Segundo stacktrace sin xposed

 java.lang.RuntimeException: Unable to start activity ComponentInfo{xx.xxx.xxxxx.xxx.xxxxx.prod/xx.xxx.xxxxx.xxx.PaymentsActivity}: java.lang.NullPointerException at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2176) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2226) at android.app.ActivityThread.access$700(ActivityThread.java:135) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1397) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4998) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:777) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:593) at dalvik.system.NativeStart.main(Native Method) Caused by: java.lang.NullPointerException at android.view.View.sendAccessibilityEventUncheckedInternal(View.java:4938) at android.view.View.sendAccessibilityEventUnchecked(View.java:4919) at android.view.View$SendViewStateChangedAccessibilityEvent.run(View.java:19433) at android.view.View$SendViewStateChangedAccessibilityEvent.runOrPost(View.java:19465) at android.view.View.notifyViewAccessibilityStateChangedIfNeeded(View.java:7265) at android.view.View.setFlags(View.java:8990) at android.view.View.setVisibility(View.java:6020) at android.view.LayoutInflater.parseInclude(LayoutInflater.java:859) at android.view.LayoutInflater.rInflate(LayoutInflater.java:745) at android.view.LayoutInflater.inflate(LayoutInflater.java:492) at android.view.LayoutInflater.inflate(LayoutInflater.java:397) at android.view.LayoutInflater.inflate(LayoutInflater.java:353) at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:290) at android.app.Activity.setContentView(Activity.java:1928) at xx.xxx.xxxxx.xxx.StandardActivity.setContentView(StandardActivity.java:289) at xx.xxx.xxxxx.xxx.PaymentsActivity.onCreate(PaymentsActivity.java:61) at android.app.Activity.performCreate(Activity.java:5243) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2140) ... 11 more 

El diseño que se establece en setContentView () contiene marcos, de lo contrario es bastante estándar y simple.

Cualquier entrada es muy apreciada 🙂

También he encontrado este mismo problema con algún código que estaba manteniendo. He podido replicar el error de forma consistente habilitando TalkBack en las opciones de accesibilidad.

En primer lugar, aquí está el método de View.java donde se utilizó la referencia nula que causó el bloqueo, desde la versión de KitKat de Android:

 void sendAccessibilityEventUncheckedInternal(AccessibilityEvent event) { if (!isShown()) { return; } onInitializeAccessibilityEvent(event); // Only a subset of accessibility events populates text content. if ((event.getEventType() & POPULATING_ACCESSIBILITY_EVENT_TYPES) != 0) { dispatchPopulateAccessibilityEvent(event); } // In the beginning we called #isShown(), so we know that getParent() is not null. getParent().requestSendAccessibilityEvent(this, event); } 

Para mí, la causa raíz resultó ser una vista personalizada que había anulado View.isShown () así:

 public boolean isShown(){ return someCondition; } 

Esto significaba que sendAccessibilityEventUncheckedInternal se ejecutaría más allá de la comprobación if (! IsShown ()) que realiza antes de continuar incluso cuando la Vista tuviera un padre nulo, y por lo tanto provocó el bloqueo.

Originalmente pensé que era un problema de concurrencia, porque asumí que el cheque isShown () había asegurado que el padre no era nulo y que la referencia al padre de la Vista había sido cambiada durante la ejecución de sendAccessibilityEventUncheckedInternal. ¡Incorrecto!

Si encuentra un problema similar, especialmente en el código que no escribió, puede evitar este bloqueo fácilmente incluyendo el resultado de la superclase isShown (suponiendo que está cambiando el código en una subclase directa de View):

 public boolean isShown(){ return super.isShown() && someCondition; } 

Mis usuarios se han estado ejecutando en el mismo problema y parece ser causado por una o más opciones de accesibilidad están activadas. Algunos de mis usuarios estaban usando el reloj inteligente Pebble, que instala una opción de accesibilidad, por lo que no es solo TalkBack, etc.

El diagnostico

Echa un vistazo a este bit de KitKat View#setFlags() método en https://github.com/android/platform_frameworks_base/blob/kitkat-mr1-release/core/java/android/view/View.java#L9006

 if (accessibilityEnabled) { ... notifyViewAccessibilityStateChangedIfNeeded( AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED); } 

Que te envía por el agujero de conejo terminando en una NullPointerException si se ejecuta antes de que la Vista se adjunte a la jerarquía de vista (es decir, no tiene ningún padre) porque en View#sendAccessibilityEventUncheckedInternal() en https://github.com/android/platform_frameworks_base/ Blob / kitkat-mr1-release / core / java / android / view / View.java # L4952 tenemos:

 getParent().requestSendAccessibilityEvent(this, event); 

Mi solución (que parece que no funcionará para usted)

Para mi aplicación, estoy creando una subclase View programática y estaba llamando View#setOnClickListener() en el constructor. En su lugar, ahora llamo View#setOnClickListener() desde

 @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); /* Due to a bug in how Android 4.4 handles accessibility options, * we can't set the onClick listener until this View has a parent or we will * get an NPE. */ setOnClickListener(this); } 

Funciona porque esta View tendrá un padre por el tiempo View#onAttachedToWindow() se llama.

Sin embargo, su seguimiento de la pila es más problemático. Estás cayendo en el agujero del conejo a través de atributos en un diseño XML. No he llegado a una idea para ti. Un pensamiento es que esto sólo debe suceder en la puesta en marcha de la aplicación – de lo contrario virtualmente todas las inflaciones de diseños XML desencadenarían el bloqueo porque hay tantas rutas que lo llevan a través de View#setFlags() . En mi aplicación, este punto parece ser el único fallo y sucede en el inicio de la aplicación. No es una idea agradable, pero una posibilidad es reordenar las cosas para inflar esta visión más tarde.

  • Puente nativo entre Python y Dalvik o AAF
  • ¿Cuáles son los datos en dalvik-LinearAlloc, dalvik-aux-estructura, dalvik-bitmap-1, dalvik-bitmap-2, dalvik-card-table, dalvik-mark-stack y dalvik-zygote?
  • ¿Cómo ver las opciones reales de gcc al construir Android desde el origen?
  • Error de instalación en Android Gingerbread y Froyo - INSTALL_FAILED_DEXOPT
  • Diferencia entre dexopt y dex2oat?
  • Prueba de Mockito + Dexmaker se bloquea cuando se ejecuta en Android <4.4
  • Mostrar tostada compleja de BroadcastReceiver
  • ¿Cómo se aplica el permiso de Android?
  • ¿Es posible cargar dinámicamente una biblioteca en tiempo de ejecución desde una aplicación de Android?
  • Dalvik auto-compilado no carga bibliotecas compartidas
  • Carga de Clase Personalizada en Dalvik con Gradle (Android New Build System)
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.