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.
- Android: obtiene los elementos de la matriz de cadenas y muestra uno por uno en la vista de texto
- Cómo almacenar un objeto Date en SharedPreferences?
- ¿Preferencias compartidas? Javax.crypto.BadPaddingException: bloque de pad corrompido sólo en algunos dispositivos
- ¿Contexto de la aplicación para SharedPreferences?
- Actualizaciones de Android en Play Store
- Cuál es la mejor manera de usar las preferencias compartidas entre las actividades
- ¿Cómo usar SharedPreferences como LocalStore, de manera más genérica?
- Guardar en SharedPreferences desde DialogPreference personalizado
- Alcance de SharedPreferences
- ¿Cuándo usar getSharedPreferences vs savedInstanceState?
- Ajuste del sonido para la notificación
- registerOnSharedPreferenceChangeListener no funciona para los cambios realizados en diferentes procesos
- onSharedPreferenceChanged no se disparó todo el tiempo
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).