包含ANR痕迹文件有很多问题,答案总是“哦,问题出在你的主题76,修复你的http调用”或者其他东西:)但我找不到任何关于如何阅读的一般指南或教程对于任何ANR,这一步都是一步一步的。有没有?我特别提出几个问题:
总是可以从我在谷歌控制台中看到的真实ANR的线程痕迹中看到问题吗?或者是否可能没有相关信息,如果我不能在本地重现ANR,我运气不好?
此信息中包含哪些主题?我想应用程序进程中有所有线程,但其余的呢?它们在某种程度上与我相关吗? (例如我的一些线程正在等待的线程等)或者还有完全不相关的进程?
Google Play控制台如何确定ANR发生的“地点” - 然后显示在ANR列表中,例如:
ANR keyDispatchingTimedOut
miesto:com.sample.myapp / myapp.activities.SplashActivity
因为SplashActivity在线程跟踪的提供文本中无处可见。
“AsyncTask#1”prio = 5 tid = 15 WAIT | group =“main”sCount = 1 dsCount = 0 obj = 0x41bb50c0 self = 0x5529a868 | sysTid = 2448 nice = 0 sched = 0/0 cgrp = apps handle = 1429609576 | state = S schedstat =(18097077 39273309 41 )java.lang.Object.wait中的utm = 1 stm = 0 core = 1(本机方法) - 等待< 0x41bb5258> (java.lang.VMThread)由tid = 15(AsyncTask#1)
保存
这总是好的,我可以认为这不是原因吗?那个情况怎么样,我在NATIVE中只有一堆线程(包括主线程)和WAIT中的一堆线程在这样等待自己?这怎么可能是ANR?
答案 0 :(得分:4)
它可能不是检测您正在寻找的ANR的总体通用方法,但一个良好的开端是为您的应用程序启用严格模式。
您将能够检查logcat,系统会在您做错事时通知您。
只需将这些行添加到您的应用程序或活动的onCreate()方法中:
if (BuildConfig.DEBUG) {
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectDiskReads()
.detectDiskWrites()
.detectAll()
.penaltyLog()
.build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectLeakedSqlLiteObjects()
.detectLeakedClosableObjects()
.penaltyLog()
.build());
}
此处有更多详情:http://developer.android.com/reference/android/os/StrictMode.html
答案 1 :(得分:4)
系统向您的应用程序发送各种事件,这些事件在UI线程上接收。如果该线程在一段时间内没有响应事件,系统会断定应用程序没有响应,并启动ANR处理。
逐点解决你的问题:
并不总是可以在堆栈跟踪中看到问题。系统服务器进程检测到存在问题,然后通知有问题的进程转储其堆栈跟踪。如果应用程序在问题发现和堆栈转储信号之间恢复,则跟踪不会告诉您太多。
您应该会看到应用中的所有主题以及您的应用。 ANR机制不会尝试确定一组相关的"线程。开始的地方是UI线程,通常是app" main"线程,看看你是否因为卡住而抓住了它。有时候应用程序很慢,没有卡住,而且缓慢的原因实际上是一个不同的过程,即吸收CPU或磁盘带宽,但是你无法在堆栈跟踪中看到它......你可能会得到一个堆栈跟踪,反映执行过去的时间点"卡住"。
"地点"是未响应的事件(在本例中为关键事件),以及系统尝试与之交互的活动。
这是正常的;当线程被停放时,你会看到#34;通过达尔维克的java.util.concurrent.locks.LockSupport.park()
。请记住,在线程等待时释放锁定,因此在这种情况下,它只是等待另一个线程出现并通知它。
解决评论中提出的观点:如果(1)本机崩溃并未完全杀死应用程序,本机崩溃可能导致ANR,这就是它的原因应该做的; (2)死亡的线程是UI线程,或者拥有UI线程正在等待的资源。如果您无法访问完整的logcat,则可以检查线程列表以确认所有线程都处于活动状态。
在查看ANR时,首先需要弄清楚的是它是永久卡住还是暂时放慢速度。对于使用该应用的人来说,这应该是显而易见的。永久冻结通常是最容易解决的,因为堆栈跟踪通常会引导您出错。从UI线程开始,遍历跟踪,直到找到一些在本机调用中旋转或卡住的代码。 (虽然它有本机调用的技巧 - 如果它说NATIVE然后它仍然在本机代码中,但如果它在堆栈顶部使用本机方法的线程上显示SUSPENDED,那么它&# 39;没有被卡住,而是从本机代码返回到托管代码。)
瞬态ANR可能更难,特别是如果它们在配置未知的客户设备上发生。如果他们在后台运行CPU基准测试,因为闪存部件出现故障导致设备停止运行,那么您的应用将会遇到不好的时间。有时堆栈跟踪指向问题的一般方向(例如this one,其中显示缓慢渲染和粗略锁定停止UI线程),其他时候在应用程序恢复正常运行后捕获跟踪