Cómo obtener algo útil de este registro ANR

Estoy luchando con ANRs por unas semanas, pero todavía me siento ciego con troncos como este . Es demasiado largo para stackoverflow y no tengo idea de qué parte podría ser útil. Sucede generalmente durante la sincronización inicial cuando hay una tonelada de la petición de la red que es procesada en el fondo (y soy casi el 100% seguro no de eso está en el hilo principal) y también estoy haciendo muchos de UI materia como poblando recyclerviews de las preferencias compartidas a través de RxJava observables por lo que estoy observando un cambio masivo en SharedPreferences y utilizando el método de muestra para manejar la posible contrapresión. Gracias por cualquier consejo, estoy totalmente perdido.

Tienes vertederos de hilos para varios procesos. Para llegar a la parte útil, puede buscar "línea Cmd" hasta que encuentre su proceso ("cz.vcelka.androidapp", el pid fue 21574).

Si obtiene un ANR que significa que su hilo principal está bloqueado de alguna manera, por lo que debe mirar su rastro de la pila. Aquí está :

 "main" prio=5 tid=1 Waiting | group="main" sCount=1 dsCount=0 obj=0x74bc2fa0 self=0xb4db6500 | sysTid=21574 nice=0 cgrp=default sched=0/0 handle=0xb6fc1b34 | state=S schedstat=( 0 0 0 ) utm=785 stm=88 core=1 HZ=100 | stack=0xbe29a000-0xbe29c000 stackSize=8MB | held mutexes= at java.lang.Object.wait!(Native method) - waiting on <0x05853836> (a java.lang.Object) at java.lang.Thread.parkFor$(Thread.java:1220) - locked <0x05853836> (a java.lang.Object) at sun.misc.Unsafe.park(Unsafe.java:299) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:158) at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:810) at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:971) at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1278) at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:203) at android.app.SharedPreferencesImpl$EditorImpl$1.run(SharedPreferencesImpl.java:366) at android.app.QueuedWork.waitToFinish(QueuedWork.java:88) at android.app.ActivityThread.handleStopActivity(ActivityThread.java:3560) at android.app.ActivityThread.-wrap20(ActivityThread.java:-1) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1373) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java.lang.reflect.Method.invoke!(Native method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

Así que su hilo principal se bloquea esperando en un SharedPreferences dentro de código SharedPreferences . Podemos ver el código fuente de SharedPreferences para obtener más información. En algún momento cuando llamó SharedPreferences.Editor.apply () , el código SharedPreferences el escribir en disco a un subproceso de trabajo. También llamado QueuedWork.add (awaitCommit) , donde awaitCommit es un Runnable que espera en la operación de escritura (por medio de CountDownLatch ), y QueuedWork.add() es un método que enqueues el trabajo que se realizará en el hilo principal cuando la actividad onPause se llama al método. Eso es lo que sucedió: onPause fue llamado, y ahora el hilo principal está atascado esperando en el hilo de trabajo para completar su operación de escritura.

Ahora el problema es que el registro que publicó está incompleto. Varios subprocesos faltan, incluido el subproceso de trabajo que nunca llamó CountDownLatch.countDown() , por lo que no es posible saber qué está causando el bloqueo. Si publicas el registro completo (para tu proceso, no creo que los otros sean útiles), probablemente podamos ayudar más.

Edit: Me di cuenta de que alguien aquí corrió en el mismo problema. Para ellos, el hilo de trabajo estaba atascado en fsync(2) . fsync puede ser realmente lento (como en varios segundos) si el archivo es grande y / o el disco está ocupado. Supongo que podría estar causando la ANR. No estoy seguro de si eso sería clasificar como un error en SharedPreferences … Parece un poco raro desencadenar posiblemente largas operaciones de bloqueo en el hilo principal, incluso si se llama desde onPause … Si este es realmente su problema, la única solución Puedo pensar en sería utilizar commit() lugar de apply() , ya que hará la escritura de forma sincrónica. Usted debe hacerlo desde un hilo de fondo, dado que en su configuración particular parece que puede tomar un tiempo bastante largo a nivel de disco!

O tal vez su archivo SharedPreferences es demasiado grande, en cuyo caso podría intentar adelgazarlo (usando una base de datos, por ejemplo).

  • ¿Cómo puedo ver el archivo de preferencias compartidas con Android Studio?
  • Cómo cambiar mediante programación la imagen de fondo de una actividad de Android
  • Validación de preferencias de Android EditText
  • Eliminación de preferencias compartidas
  • ¿Restablecer SharedPreferences?
  • Cifrar datos en SharedPreferences
  • Cómo mostrar sólo una vez Iniciar sesión y luego después de iniciar la aplicación directamente en android
  • Cómo cambiar los valores en la preferencia compartida
  • Hacer que una actividad aparezca sólo una vez, cuando se inicia la aplicación
  • Android: copiar / duplicar las preferencias compartidas
  • Cómo guardar la ruta de la imagen utilizando las preferencias compartidas
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.