Android 如何分析SharedReference中的ANR

Android 如何分析SharedReference中的ANR,android,sharedpreferences,android-anr-dialog,Android,Sharedpreferences,Android Anr Dialog,在SharedReferences中遇到ANR,不知道如何查找问题 这里有跟踪的三个部分,大多数其他线程是“等待”或“定时等待”。“main”线程因countdownlatch.await()而被阻止。 第二个线程“pool-1-thread-1”正在等待fsync。 最后一个是试着读一些东西 我认为第二个线程阻塞了主线程,因为如果这个线程无法完成,它将不会调用countdownlatch.countdown(),因此主线程必须等待 但我不明白为什么它会停在fsync中。第三个线程与此相关吗 螺

在SharedReferences中遇到ANR,不知道如何查找问题

这里有跟踪的三个部分,大多数其他线程是“等待”或“定时等待”。“main”线程因countdownlatch.await()而被阻止。 第二个线程“pool-1-thread-1”正在等待fsync。 最后一个是试着读一些东西

我认为第二个线程阻塞了主线程,因为如果这个线程无法完成,它将不会调用countdownlatch.countdown(),因此主线程必须等待

但我不明白为什么它会停在fsync中。第三个线程与此相关吗

螺纹1

"main" prio=5 tid=1 WAIT
| group="main" sCount=1 dsCount=0 obj=0x418efe58 self=0x4180b6e8
| sysTid=4178 nice=-6 sched=0/0 cgrp=apps handle=1074565460
| state=S schedstat=( 3385090416 1929697750 7848 ) utm=278 stm=60 core=3
at java.lang.Object.wait(Native Method)
- waiting on <0x418eff28> (a java.lang.VMThread) held by tid=1 (main)
at java.lang.Thread.parkFor(Thread.java:1205)
at sun.misc.Unsafe.park(Unsafe.java:325)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:157)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:813)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:973)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1281)
at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:202)
at android.app.SharedPreferencesImpl$EditorImpl$1.run(SharedPreferencesImpl.java:364)
at android.app.QueuedWork.waitToFinish(QueuedWork.java:88)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2697)
at android.app.ActivityThread.access$2100(ActivityThread.java:138)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1296)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5095)
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:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
螺纹3

"Thread-5346" prio=5 tid=48 SUSPENDED
| group="main" sCount=1 dsCount=0 obj=0x42b9e3c0 self=0x6278f280
| sysTid=4841 nice=0 sched=0/0 cgrp=apps handle=1652085768
| state=S schedstat=( 6396036717 2412660825 15121 ) utm=612 stm=27 core=1
at java.lang.StackTraceElement.<init>(StackTraceElement.java:~61)
at java.lang.Throwable.nativeGetStackTrace(Native Method)
at java.lang.Throwable.getInternalStackTrace(Throwable.java:264)
at java.lang.Throwable.getStackTrace(Throwable.java:200)
at org.apache.commons.logging.impl.Jdk14Logger.log(Jdk14Logger.java:88)
at org.apache.commons.logging.impl.Jdk14Logger.debug(Jdk14Logger.java:113)
at org.apache.http.impl.conn.Wire.wire(Wire.java:64)
at org.apache.http.impl.conn.Wire.input(Wire.java:116)
at org.apache.http.impl.conn.LoggingSessionInputBuffer.read(LoggingSessionInputBuffer.java:74)
at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:174)
at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:159)
at org.qiyi.android.coreplayer.a.aux.a(SourceFile:206)
at org.qiyi.android.coreplayer.a.aux.a(SourceFile:140)
at org.qiyi.android.coreplayer.a.aux.a(SourceFile:105)
at org.qiyi.android.coreplayer.a.com7.a(SourceFile:361)
at org.qiyi.android.coreplayer.a.nul.run(SourceFile:158)
at java.lang.Thread.run(Thread.java:841)
“线程-5346”优先级=5 tid=48挂起
|group=“main”scont=1 dsCount=0 obj=0x42b9e3c0 self=0x6278f280
|sysTid=4841 nice=0 sched=0/0 cgrp=apps handle=1652085768
|state=S schedstat=(6396036717 241260825 15121)utm=612 stm=27 core=1
位于java.lang.StackTraceeElement。(stackTraceeElement.java:~61)
位于java.lang.Throwable.nativeGetStackTrace(本机方法)
位于java.lang.Throwable.getInternalStackTrace(Throwable.java:264)
位于java.lang.Throwable.getStackTrace(Throwable.java:200)
位于org.apache.commons.logging.impl.Jdk14Logger.log(Jdk14Logger.java:88)
位于org.apache.commons.logging.impl.Jdk14Logger.debug(Jdk14Logger.java:113)
位于org.apache.http.impl.conn.Wire.Wire(Wire.java:64)
位于org.apache.http.impl.conn.Wire.input(Wire.java:116)
位于org.apache.http.impl.conn.LoggingSessionInputBuffer.read(LoggingSessionInputBuffer.java:74)
位于org.apache.http.impl.io.ContentLengthinInputStream.read(contentLengthinInputStream.java:174)
位于org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:159)
位于org.qiyi.android.coreplayer.a.aux.a(源文件:206)
位于org.qiyi.android.coreplayer.a.aux.a(源文件:140)
位于org.qiyi.android.coreplayer.a.aux.a(源文件:105)
位于org.qiyi.android.coreplayer.a.com7.a(源文件:361)
位于org.qiyi.android.coreplayer.a.nul.run(源文件:158)
运行(Thread.java:841)

我已经知道发生了什么

从三个轨迹中,我们可以看到:
-共享首选项被文件同步阻止。
-fsync正在等待某些内容(应该是磁盘)。
-一个线程正在执行磁盘操作

在我仔细检查了源代码之后,很多SP的get/set被用来记录应用程序启动时的状态。同时,有一个新的线程试图从服务器下载大数据,比如.jar或.so。 对于一些旧设备,下载大数据可能会发生繁重的GC和“apache”库尝试通过“Wire”记录所有内容。因此,有时,它会花费太长时间,导致SP超时

解决方法是
-关闭apache日志
-将状态保存在内存中,并将它们设置为一个对象。

-将一些后台行为从初始化部分移开。

这是由于Android的SharedReferences实现中存在一个bug:


目前,任何使用
SharedReferences.Editor.apply()
的行为都像是在为ANR计划定时炸弹。

请同时发布您的代码。所以我们可以很好地理解这个问题?事实上,这是一个大项目,我不知道这段代码的哪一部分出现了。。。SharedReference用于太多的地方。您好,我刚刚注意到您的问题,似乎您遇到了与此问题相同的问题:stackoverflow.com/q/37549578。我试图回答另一个问题,但我不确定该怎么办。简而言之,
onPause
调用从
SharedReferences
代码触发了主线程上的等待。不确定这是否是
SharedReferences
中的错误。您可以尝试从后台线程使用
commit()
,而不是
apply()
。或者您可以减小
SharedReferences
文件的大小,看看它是否同步得更快。您仍然看到这个问题吗?是因为你用了“提交”而不是“应用”吗?或者只是阅读SharedReferences?我在SharedReferences.Editor.commit()上看到,在主线程中执行commit肯定会导致ANR,所以这并不奇怪。这个错误在2018年被标记为“已修复”。但它现在仍在生产中发生。这是否意味着修复程序在Android框架代码中?我不明白,通过apache lib下载文件与SP有什么关系?
"Thread-5346" prio=5 tid=48 SUSPENDED
| group="main" sCount=1 dsCount=0 obj=0x42b9e3c0 self=0x6278f280
| sysTid=4841 nice=0 sched=0/0 cgrp=apps handle=1652085768
| state=S schedstat=( 6396036717 2412660825 15121 ) utm=612 stm=27 core=1
at java.lang.StackTraceElement.<init>(StackTraceElement.java:~61)
at java.lang.Throwable.nativeGetStackTrace(Native Method)
at java.lang.Throwable.getInternalStackTrace(Throwable.java:264)
at java.lang.Throwable.getStackTrace(Throwable.java:200)
at org.apache.commons.logging.impl.Jdk14Logger.log(Jdk14Logger.java:88)
at org.apache.commons.logging.impl.Jdk14Logger.debug(Jdk14Logger.java:113)
at org.apache.http.impl.conn.Wire.wire(Wire.java:64)
at org.apache.http.impl.conn.Wire.input(Wire.java:116)
at org.apache.http.impl.conn.LoggingSessionInputBuffer.read(LoggingSessionInputBuffer.java:74)
at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:174)
at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:159)
at org.qiyi.android.coreplayer.a.aux.a(SourceFile:206)
at org.qiyi.android.coreplayer.a.aux.a(SourceFile:140)
at org.qiyi.android.coreplayer.a.aux.a(SourceFile:105)
at org.qiyi.android.coreplayer.a.com7.a(SourceFile:361)
at org.qiyi.android.coreplayer.a.nul.run(SourceFile:158)
at java.lang.Thread.run(Thread.java:841)