写点什么

Android ANR:Application Not Responding 详解

发布于: 2021 年 11 月 06 日

日志关键字:Timeout of broadcast BroadcastRecord


  • ServiceTimeout —— Service 在特定的时间内未处理完成导致 ANR 发生。(限制:前台服务 20s;后台服务 200s);


日志关键字:Timeout executing service


  • ContentProviderTimeout —— 内容提供者,在 10s 内未处理完成导致 ANR 发生;


日志关键字:`Timeout publishing conte


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


nt providers`

三、ANR 的产生原因

  • 主线程被 IO 操作(从 4.0 之后网络 IO 不允许在主线程中)阻塞


主线程中错误的操作,比如 Thread.wait 或者 Thread.sleep 等 Android 系统会监控程序的响应状况,导致的主线程等待超时,一旦出现下面两种情况,则弹出 ANR 对话框。


  • 主线程中存在耗时的计算:


例如大量的数据库读写,耗时的网络情况,高强度的硬件计算等。


  • BroadcastReceiver 未在 10 秒内完成相关的处理

  • Service 在特定的时间内无法处理完成 20 秒

四、怎么避免 ANR:

  1. 使用 AsyncTask 处理耗时 IO 操作。

  2. 使用 Thread 或者 HandlerThread 时,调用**Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND)**设置优先级,否则仍然会降低程序响应,因为默认 Thread 的优先级和主线程相同。

  3. 使用 Handler 处理工作线程结果,而不是使用**Thread.wait()或者 Thread.sleep()**来阻塞主线程。

  4. Activity 的 onCreate 和 onResume 回调中尽量避免耗时的代码。

  5. BroadcastReceiver 中 onReceive 代码也要尽量减少耗时,建议使用 IntentService 处理。


将所有耗时操作,比如访问网络,Socket 通信,查询大量 sql 语句,复杂逻辑计算等都放在子线程中去,然后通过 handler.sendMessage、runonUIThread、AsyncTask、RxJava 等方式更新 UI。

五、发生了 ANR 的情况,如何解决:

如果在已经尽量避免的情况下,还是发生了 ANR 的情况,我们可以根据以下的步骤进行问题定位与分析:

1.问题分析
  • 导出 ANR 日志信息,根据日志信息,判断确认发生 ANR 的包名类名,进程号,发生时间,导致 ANR 原因类型等。

  • 关注系统资源信息,包括 ANR 发生前后的 CPU,内存,IO 等系统资源的使用情况。

  • 查看主线程状态,关注主线程是否存在耗时、死锁、等锁等问题,判断该 ANR 是 App 导致还是系统导致的。

  • 结合应用日志,代码或源码等,分析 ANR 问题发生前,应用是否有异常,其中具体问题具体分析。

2.导出 ANR 日志

NR 问题发生时,系统会收集 ANR 相关的日志信息,CPU 使用情况,trace 日志也就是各线程执行情况等信息,生成一个 traces.txt 的文件并且放在**/data/anr/**路径下。


注意:每一次新的 ANR 问题的发生,会把之前的 ANR 信息覆盖掉。


我们可以通过 adb 命令将 traces 文件导出到本地。


adb root


adb shell ls /data/anr


adb pull /data/anr/<filename>


  • 读取关键日志信息


  1. 在 log 中找到 ANR 发生信息:

评论

发布
暂无评论
Android ANR:Application Not Responding详解