ANR 详解

简介

ANR 全称是 Application Not Responding,意为“应用不响应”,俗称卡顿。

在 Android APP 的主要组件,默认都是运行在主线程(或 UI 线程),如果在这个线程中执行了长时间的操作,未能及时响应用户的输入,系统就会杀死这个 APP,回收资源。

跟 APP 相关的组件及其触发 ANR 时间:

  1. 按钮和触摸事件,5s
  2. Service 20s
  3. Broadcast 前台 10s,后台 60s

信息

系统在捕获到 ANR 之后,会在 /data/anr/traces.txt 写进程信息,并且会在对应的线程设置 ANR Message。

Bugtags 会捕获进程中所有的线程的堆栈,连带 ANR Message 发送到后台。

线程与堆栈

Bugtags 会将 ANR 组装成一个 io.bugtags.platform.AnrError, 形如:

样例

ANR Message

附带的错误信息,是类似这样的。

ANR in com.bugtags.demo (com.bugtags.demo/.FunctionsActivity)
Reason: keyDispatchingTimedOut
Load: 13.18 / 16.73 / 19.9
CPU usage from 12159ms to 0ms ago with 99% awake:
  99% 23190/com.bugtags.demo: 99% user + 0% kernel
  1% 2291/system_server: 0.5% user + 0.4% kernel / faults: 360 minor
  0.3% 2546/com.android.systemui: 0.2% user + 0% kernel / faults: 3 minor
  0.1% 1930/surfaceflinger: 0% user + 0% kernel
  0.1% 22748/kworker/0:0: 0% user + 0.1% kernel
  0% 743/s3c-fb-vsync: 0% user + 0% kernel
  0% 903/irq/387-melfas-: 0% user + 0% kernel
  0% 1147/mmcqd/0: 0% user + 0% kernel
  0% 1922/netd: 0% user + 0% kernel
  0% 1942/gpsd: 0% user + 0% kernel
  0% 3146/logcat: 0% user + 0% kernel
  0% 4026/com.wandoujia.phoenix2: 0% user + 0% kernel
  0% 10880/wpa_supplicant: 0% user + 0% kernel
  0% 22675/kworker/u:18: 0% user + 0% kernel
  0% 22746/kworker/u:32: 0% user + 0% kernel
  0% 25017/logcat: 0% user + 0% kernel
  0% 27886/cn.dajiahui.master:xg_service_v2: 0% user + 0% kernel
  0% 31002/logcat: 0% user + 0% kernel
33% TOTAL: 33% user + 0.4% kernel + 0% softirq
CPU usage from 1190ms to 1710ms later:
  98% 23190/com.bugtags.demo: 98% user + 0% kernel
    98% 23190/om.bugtags.demo: 98% user + 0% kernel
  3.8% 2291/system_server: 0% user + 3.8% kernel / faults: 23 minor
    3.8% 2463/InputDispatcher: 0% user + 3.8% kernel
  1.4% 10853/dhd_dpc: 0% user + 1.4% kernel

从这份信息中,可以看到,错误的类型,出处。

ANR in com.bugtags.demo (com.bugtags.demo/.FunctionsActivity)
Reason: keyDispatchingTimedOut

注意查看 CPU 使用率:

 99% 23190/com.bugtags.demo: 99% user + 0% kernel

这标示主要的 CPU 时间都消耗在这个 APP 中,很有可能就是一个死循环或者长时间的操作。