"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)
SharedPreferences
代码中的一个 CountDownLatch
。我们可以查看 SharedPreferences 的源代码以了解更多信息。在某个时刻,当你调用 SharedPreferences.Editor.apply() 时,SharedPreferences
代码将写入磁盘的操作排队到工作线程中。它还调用了 QueuedWork.add(awaitCommit),其中 awaitCommit
是一个等待写操作完成的 Runnable
(通过 CountDownLatch
实现),而 QueuedWork.add()
是一个方法,当活动的 onPause
方法被调用时,将工作排队在主线程上执行。这就是发生的情况:调用了 onPause
,现在主线程被卡在等待工作线程完成其写入操作上了。CountDownLatch.countDown()
的工作线程,因此无法确定死锁的原因。如果您发布整个日志(针对您的进程,我认为其他日志不会有用),我们可能可以提供更多帮助。fsync(2)
中被卡住了。如果文件很大和/或磁盘很忙,fsync
可能会非常慢(多达几秒钟)。我想这可能会导致ANR。我不确定这是否属于SharedPreferences
中的错误...即使从onPause
调用,似乎在主线程上触发可能长时间阻塞的操作也有点奇怪...如果确实是您的问题,我能想到的唯一解决方法就是使用commit()
而不是apply()
,因为它将同步进行写入。鉴于在您的特定设置中似乎需要花费相当长的时间才能刷新到磁盘,您应该从后台线程中执行此操作!
或者,也许您的SharedPreferences
文件太大了,您可以尝试缩小它(例如使用数据库)。
apply()
到 commit()
的转变真的显著地改善了情况,因为我已经在后台线程中调用了它。虽然我仍然可以通过非常努力的尝试获取 ARN,但我猜下一个逻辑步骤现在是简化 SharedPreferences
的工作。 - Semanticer