为了账号安全,请及时绑定邮箱和手机立即绑定

Android - 如何调查ANR?

Android - 如何调查ANR?

慕容708150 2019-08-24 14:32:03
Android - 如何调查ANR?有没有办法找出我的应用程序扔ANR(应用程序无响应)的位置。我看了/ data中的traces.txt文件,我看到了我的应用程序的跟踪。这就是我在追踪中看到的。DALVIK THREADS:"main" prio=5 tid=3 TIMED_WAIT  | group="main" sCount=1 dsCount=0 s=0 obj=0x400143a8   | sysTid=691 nice=0 sched=0/0 handle=-1091117924   at java.lang.Object.wait(Native Method)   - waiting on <0x1cd570> (a android.os.MessageQueue)   at java.lang.Object.wait(Object.java:195)   at android.os.MessageQueue.next(MessageQueue.java:144)   at android.os.Looper.loop(Looper.java:110)   at android.app.ActivityThread.main(ActivityThread.java:3742)   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:739)   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:497)   at dalvik.system.NativeStart.main(Native Method)"Binder Thread #3" prio=5 tid=15 NATIVE  | group="main" sCount=1 dsCount=0 s=0 obj=0x434e7758   | sysTid=734 nice=0 sched=0/0 handle=1733632   at dalvik.system.NativeStart.run(Native Method)"Binder Thread #2" prio=5 tid=13 NATIVE  | group="main" sCount=1 dsCount=0 s=0 obj=0x433af808   | sysTid=696 nice=0 sched=0/0 handle=1369840   at dalvik.system.NativeStart.run(Native Method)"Binder Thread #1" prio=5 tid=11 NATIVE  | group="main" sCount=1 dsCount=0 s=0 obj=0x433aca10   | sysTid=695 nice=0 sched=0/0 handle=1367448   at dalvik.system.NativeStart.run(Native Method)"JDWP" daemon prio=5 tid=9 VMWAIT  | group="system" sCount=1 dsCount=0 s=0 obj=0x433ac2a0   | sysTid=694 nice=0 sched=0/0 handle=1367136   at dalvik.system.NativeStart.run(Native Method)"Signal Catcher" daemon prio=5 tid=7 RUNNABLE  | group="system" sCount=0 dsCount=0 s=0 obj=0x433ac1e8   | sysTid=693 nice=0 sched=0/0 handle=1366712我怎样才能找出问题所在?跟踪中的方法都是SDK方法。
查看完整描述

3 回答

?
30秒到达战场

TA贡献1828条经验 获得超6个赞

当在“主”线程中发生一些长操作时,会发生ANR。这是事件循环线程,如果它很忙,Android无法处理应用程序中的任何其他GUI事件,从而抛出ANR对话框。

现在,在您发布的跟踪中,主线程似乎做得很好,没有问题。它在MessageQueue中空闲,等待另一条消息进来。在你的情况下,ANR可能是一个更长的操作,而不是永久阻塞线程的东西,所以事件线程在操作完成后恢复,你的跟踪经历了在ANR之后。

如果ANR是永久性块(例如,死锁获取某些锁),则检测ANR发生的位置很容易,但如果它只是暂时的延迟则更难。首先,查看代码并查找可用的点和长时间运行的操作。示例可以包括在事件线程内使用套接字,锁,线程休眠和其他阻塞操作。你应该确保这些都发生在不同的线程中。如果没有任何问题,请使用DDMS并启用线程视图。这会显示应用程序中的所有线程与您拥有的跟踪类似。重现ANR,同时刷新主线程。这应该向你展示ANR时正在发生的事情


查看完整回答
反对 回复 2019-08-24
?
慕村9548890

TA贡献1884条经验 获得超4个赞

考虑使用ANR-Watchdog库以高细节精确跟踪和捕获ANR堆栈跟踪。然后,您可以将它们发送到崩溃报告库。我建议setReportMainThreadOnly()在这种情况下使用。您可以让应用程序抛出冻结点的非致命异常,或者在ANR发生时强制退出应用程序。

请注意,发送到Google Play开发者控制台的标准ANR报告通常不够准确,无法确定问题所在。这就是需要第三方库的原因。


查看完整回答
反对 回复 2019-08-24
  • 3 回答
  • 0 关注
  • 554 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信