一.定义与产生机制
1.定义
ANR是ApplicationNotResponse简称,是指应用程序在一定的时间内响应未完成或响应时间过长,由此产生的ANR,它是发生在主线程中。
2.产生机制
我们知道Android基于事件驱动,ANR也是基于主线程的Looper机制,在事件触发前,发起一个延迟消息,然后会在特定的位置移除这个消息,如果未能移除就会报ANR,以下就是触发机制的流程,基本上可以概括为,预埋点,移除预埋点,如果未能移除就会报错,相关Service、BroadCastReceive等埋点和移除可以自行查看下源码,但是流程可以概括如下:
二.ANR分类
1.常见的ANR
-
- 点击事件(Input event dispatching time out ):超过5秒未响应; - Service( Timeout excuting service):前台20秒,后台200秒服务未启动完成; - BroadcastReceiver(Timeout of broadcast receiver):前台10秒,后台60秒,未处理完onReceiver中的代码; - contentProvider(Timeout publishing content providers):publish在10秒内未处理完。
2.其他的ANR
-
- Binder导致的:Binder通讯数据量过大、Binder线程池过多,超过15个; - 线程阻塞或死锁; - 频繁GC导致的事件处理过长。
三.定位与分析
1.日志文件定位
发生anr后日志会被保存在data/anr中,在 traces.txt 找到发生 ANR 时间节点、主线程的状态、ANR 类型和事故点。
2.日志过滤定位
logcat-v time打印mainlog,在 mainlog 日志查看 CPU 状态,根据以上步骤收集的信息大致判断问题原因是 CPU 问题还是 非 CPU 问题,如果是非 CPU 问题,那么看 GC 处理信息,在 traces.txt 分析 CG 信息,结合项目代码和以上步骤分析到的原因,定位到问题修复 ANR。
线程状态:
3.样例分析
1.点击事件超时分析
我们从日志里得到anr事件类型、PID、CPU使用状况:
class MainActivity:AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
fun anrTest(view: View) {
Thread.sleep(6*1000)
}
}
1.日志打印:
07-23 07:44:43.621 I/ActivityManager( 535): Done dumping
07-23 07:44:43.622 E/ActivityManager( 535): ANR in com.seven.anr (com.seven.anr/.MainActivity)
07-23 07:44:43.622 E/ActivityManager( 535): PID: 29965
07-23 07:44:43.622 E/ActivityManager( 535): Reason: Input dispatching timed out (3a76ec7 com.seven.anr/com.seven.anr.MainActivity (server) is not responding. Waited 5003ms for KeyEvent(deviceId=0, source=0x00000301, displayId=-1, action=DOWN, flags=0x00000008, keyCode=4, scanCode=158, metaState=0x00000000, repeatCount=0), policyFlags=0x62000000)
07-23 07:44:43.622 E/ActivityManager( 535): Parent: com.seven.anr/.MainActivity
07-23 07:44:43.622 E/ActivityManager( 535): Load: 0.2 / 0.15 / 0.13
07-23 07:44:43.622 E/ActivityManager( 535): ----- Output from /proc/pressure/memory -----
07-23 07:44:43.622 E/ActivityManager( 535): some avg10=0.00 avg60=0.00 avg300=0.00 total=0
07-23 07:44:43.622 E/ActivityManager( 535): full avg10=0.00 avg60=0.00 avg300=0.00 total=0
07-23 07:44:43.622 E/ActivityManager( 535): ----- End output from /proc/pressure/memory -----
07-23 07:44:43.622 E/ActivityManager( 535):
07-23 07:44:43.622 E/ActivityManager( 535): CPU usage from 128501ms to 0ms ago (2025-07-23 07:42:33.813 to 2025-07-23 07:44:42.314):
07-23 07:44:43.622 E/ActivityManager( 535): 3.1% 293/android.hardware.bluetooth@1.1-service.sim: 0% user + 3.1% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 2.3% 303/android.hardware.graphics.composer@2.3-service: 0% user + 2.3% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 2% 27831/transport: 0% user + 1.9% kernel / faults: 27 minor
07-23 07:44:43.622 E/ActivityManager( 535): 1.9% 535/system_server: 0% user + 1.8% kernel / faults: 14933 minor
07-23 07:44:43.622 E/ActivityManager( 535): 1.7% 173/logd: 0% user + 1.7% kernel / faults: 10 minor
07-23 07:44:43.622 E/ActivityManager( 535): 0.7% 324/surfaceflinger: 0% user + 0.7% kernel / faults: 115 minor
07-23 07:44:43.622 E/ActivityManager( 535): 0.6% 311/android.hardware.sensors@2.1-service.multihal: 0% user + 0.6% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 0% 1076/com.android.launcher3: 0% user + 0% kernel / faults: 340 minor
07-23 07:44:43.622 E/ActivityManager( 535): 0% 302/android.hardware.graphics.allocator@3.0-service: 0% user + 0% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 0.2% 372/adbd: 0% user + 0.2% kernel / faults: 708 minor
07-23 07:44:43.622 E/ActivityManager( 535): 0.2% 29823/com.seven.memory: 0% user + 0.2% kernel / faults: 2008 minor
07-23 07:44:43.622 E/ActivityManager( 535): 0.1% 26/ksoftirqd/3: 0% user + 0.1% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 0.1% 700/com.android.systemui: 0% user + 0.1% kernel / faults: 74 minor
07-23 07:44:43.622 E/ActivityManager( 535): 0% 291/android.hardware.audio.service.ranchu: 0% user + 0% kernel / faults: 10 minor
07-23 07:44:43.622 E/ActivityManager( 535): 0.1% 10/rcu_preempt: 0% user + 0.1% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 0.1% 917/com.android.phone: 0% user + 0.1% kernel / faults: 253 minor
07-23 07:44:43.622 E/ActivityManager( 535): 0.1% 1894/com.android.permissioncontroller: 0% user + 0.1% kernel / faults: 821 minor
07-23 07:44:43.622 E/ActivityManager( 535): 0% 420/audioserver: 0% user + 0% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 0% 26886/process-tracker: 0% user + 0% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 0% 27694/process-tracker: 0% user + 0% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 0% 16/ksoftirqd/1: 0% user + 0% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 0% 379/traced_probes: 0% user + 0% kernel / faults: 2 minor
07-23 07:44:43.622 E/ActivityManager( 535): 0% 402/llkd: 0% user + 0% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 0% 9/ksoftirqd/0: 0% user + 0% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 0% 27685/logcat: 0% user + 0% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 0% 205/jbd2/dm-5-8: 0% user + 0% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 0% 785/android.hardware.gnss@2.0-service.ranchu: 0% user + 0% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 0% 29796/kworker/3:2-events_power_efficient: 0% user + 0% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 0% 31/kauditd: 0% user + 0% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 0% 286/statsd: 0% user + 0% kernel / faults: 4 minor
07-23 07:44:43.622 E/ActivityManager( 535): 0% 388/iorapd: 0% user + 0% kernel / faults: 71 minor
07-23 07:44:43.622 E/ActivityManager( 535): 0% 29535/kworker/0:1-mm_percpu_wq: 0% user + 0% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 0% 29904/kworker/u8:2-events_unbound: 0% user + 0% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 0% 21/ksoftirqd/2: 0% user + 0% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 0% 142/kworker/1:1H-kblockd: 0% user + 0% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 0% 175/servicemanager: 0% user + 0% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 0% 287/netd: 0% user + 0% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 0% 288/zygote64: 0% user + 0% kernel / faults: 173 minor
07-23 07:44:43.622 E/ActivityManager( 535): 0% 304/android.hardware.health@2.1-service: 0% user + 0% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 0% 380/traced: 0% user + 0% kernel / faults: 20 minor
07-23 07:44:43.622 E/ActivityManager( 535): 0% 394/wificond: 0% user + 0% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 0% 396/libgoldfish-rild: 0% user + 0% kernel / faults: 14 minor
07-23 07:44:43.622 E/ActivityManager( 535): 0% 401/android.hardware.biometrics.fingerprint@2.1-service: 0% user + 0% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 0% 426/netmgr: 0% user + 0% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 0% 430/hostapd_nohidl: 0% user + 0% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 0% 676/wpa_supplicant: 0% user + 0% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 0% 1268/com.android.inputmethod.latin: 0% user + 0% kernel / faults: 1 minor
07-23 07:44:43.622 E/ActivityManager( 535): 0% 4208/com.android.packageinstaller: 0% user + 0% kernel / faults: 2 minor
07-23 07:44:43.622 E/ActivityManager( 535): 0% 29253/kworker/1:3-events: 0% user + 0% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 0% 29869/kworker/u8:1-events_unbound: 0% user + 0% kernel
07-23 07:44:43.622 E/ActivityManager( 535): +0% 29965/com.seven.anr: 0% user + 0% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 2.5% TOTAL: 0% user + 2.5% kernel + 0% iowait
07-23 07:44:43.622 E/ActivityManager( 535): CPU usage from 22ms to 303ms later (2025-07-23 07:44:42.336 to 2025-07-23 07:44:42.617):
07-23 07:44:43.622 E/ActivityManager( 535): 53% 1076/com.android.launcher3: 0% user + 53% kernel / faults: 40 minor
07-23 07:44:43.622 E/ActivityManager( 535): 44% 1497/RenderThread: 0% user + 44% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 8.8% 1076/droid.launcher3: 0% user + 8.8% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 4.4% 1121/UiThreadHelper: 0% user + 4.4% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 4.4% 1122/launcher-loader: 0% user + 4.4% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 40% 303/android.hardware.graphics.composer@2.3-service: 0% user + 40% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 40% 303/composer@2.3-se: 0% user + 40% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 4% 354/: 0% user + 4% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 24% 324/surfaceflinger: 0% user + 24% kernel / faults: 15 minor
07-23 07:44:43.622 E/ActivityManager( 535): 8.2% 324/surfaceflinger: 0% user + 8.2% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 4.1% 435/surfaceflinger: 0% user + 4.1% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 4.1% 454/app: 0% user + 4.1% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 4.1% 1228/Binder:324_5: 0% user + 4.1% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 25% 535/system_server: 0% user + 25% kernel / faults: 251 minor
07-23 07:44:43.622 E/ActivityManager( 535): 12% 30010/AnrConsumer: 0% user + 12% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 4.2% 553/android.ui: 4.2% user + 0% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 4.2% 4969/Binder:535_1F: 0% user + 4.2% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 25% 700/com.android.systemui: 4.2% user + 21% kernel / faults: 433 minor
07-23 07:44:43.622 E/ActivityManager( 535): 8.5% 1189/RenderThread: 0% user + 8.5% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 4.2% 700/ndroid.systemui: 0% user + 4.2% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 4.2% 716/HeapTaskDaemon: 0% user + 4.2% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 4.2% 719/FinalizerDaemon: 0% user + 4.2% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 18% 29965/com.seven.anr: 0% user + 18% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 14% 29987/RenderThread: 0% user + 14% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 12% 302/android.hardware.graphics.allocator@3.0-service: 0% user + 12% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 12% 349/HwBinder:302_2: 0% user + 12% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 7.3% 173/logd: 0% user + 7.3% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 7.3% 187/logd.auditd: 0% user + 7.3% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 4.6% 27831/transport: 0% user + 4.6% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 4.6% 27843/DetectPable: 0% user + 4.6% kernel
07-23 07:44:43.622 E/ActivityManager( 535): 58% TOTAL: 3% user + 53% kernel + 1% iowait + 1% softirq
07-23 07:44:43.622 I/ActivityManager( 535): Killing 29965:com.seven.anr/u0a150 (adj 900): bg anr
07-23 07:44:43.623 D/ActivityManager( 535): Completed ANR of com.seven.anr in 1309ms, latency 0ms
07-23 07:44:43.625 I/DropBoxManagerService( 535): add tag=data_app_anr isTagEnabled=true flags=0x2
07-23 07:44:43.647 I/Zygote ( 288): Process 29965 exited due to signal 9 (Killed)
07-23 07:44:43.673 I/libprocessgroup( 535): Successfully killed process cgroup uid 10150 pid 29965 in 50ms
07-23 07:44:44.526 W/audit ( 0): audit_lost=519121 audit_rate_limit=5 audit_backlog_limit=64
如果某些进程的 CPU 占用百分比较高,几乎占用了所有 CPU 资源,而发生 ANR 的进程(一般说的是我们的 app 进程)CPU 占用为 0% 或非常低,则认为 CPU 资源被占用,app 进程没有被分配足够的资源,从而发生了 ANR。这种情况多数可以认为是系统状态的问题,并不是由应用造成的(简单讲就是其他进程 CPU 使用率非常高自己低,就是系统资源分配不足导致)。如果发生 ANR 的进程(一般说的是我们的 app 进程)CPU 占用较高,如到了 80% 或 90% 以上,则可以怀疑应用内一些代码不合理消耗掉了 CPU 资源,如出现了死循环或者后台有许多线程执行任务等等原因,这就要结合 traces.txt 和 ANR 前后的 mainlog 日志进一步分析(简单理解就是 IO 非常频繁,要么死循环了,要么上锁了)如果 CPU 总用量不高,该进程和其他进程的占用过高,这有一定概率是由于某些主线程的操作就是耗时过长,或者是由于主进程被锁造成的。
2.从traces.txt查看具体主线程状态
"main" prio=5 tid=1 Sleeping
| group="main" sCount=1 dsCount=0 flags=1 obj=0x72d6f188 self=0x7257818be010
| sysTid=30219 nice=-10 cgrp=top-app sched=0/0 handle=0x7258a779a4f8
| state=S schedstat=( 685524155 62491498 380 ) utm=22 stm=45 core=1 HZ=100
| stack=0x7ffd6e674000-0x7ffd6e676000 stackSize=8192KB
| held mutexes=
at java.lang.Thread.sleep(Native method)
- sleeping on <0x00004564> (a java.lang.Object)
at java.lang.Thread.sleep(Thread.java:442)
- locked <0x00004564> (a java.lang.Object)
at java.lang.Thread.sleep(Thread.java:358)
at com.seven.anr.MainActivity.anrTest(MainActivity.kt:25)
at java.lang.reflect.Method.invoke(Native method)
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:468)
at android.view.View.performClick(View.java:7448)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1202)
at android.view.View.performClickInternal(View.java:7425)
at android.view.View.access$3600(View.java:810)
at android.view.View$PerformClick.run(View.java:28305)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
2.同步锁样例分析
// 一段由synchronized锁引起的anr,子线程调用主线程的同步方法,
// 由于testAnr和initView是同一个锁,这样主线程和子线程抢占同步锁,导致了anr。
fun deadLock(view: View) {
Thread {
testAnr()
}.start()
try {
Thread.sleep(1000)
} catch (e: InterruptedException) {
e.printStackTrace();
}
//一直在等待锁
initView()
}
@Synchronized
private fun testAnr() {
println("can run anr")
//一直没有释放锁
SystemClock.sleep((30 * 1000).toLong())
}
@Synchronized
private fun initView() {
println("can run init")
}
}
1.日志打印
07-23 08:06:46.240 E/ActivityManager( 535): ANR in com.seven.anr (com.seven.anr/.MainActivity)
07-23 08:06:46.240 E/ActivityManager( 535): PID: 30467
07-23 08:06:46.240 E/ActivityManager( 535): Reason: Input dispatching timed out (d16d452 com.seven.anr/com.seven.anr.MainActivity (server) is not responding. Waited 5002ms for MotionEvent(deviceId=11, source=0x00005002, displayId=0, action=DOWN, actionButton=0x00000000, flags=0x00000000, metaState=0x00000000, buttonState=0x00000000, classification=NONE, edgeFlags=0x00000000, xPrecision=68.3, yPrecision=41.0, xCursorPosition=nan, yCursorPosition=nan, pointers=[0: (282.0, 326.0)]), policyFlags=0x62000000)
07-23 08:06:46.240 E/ActivityManager( 535): Parent: com.seven.anr/.MainActivity
07-23 08:06:46.240 E/ActivityManager( 535): Load: 0.13 / 0.11 / 0.12
07-23 08:06:46.240 E/ActivityManager( 535): ----- Output from /proc/pressure/memory -----
07-23 08:06:46.240 E/ActivityManager( 535): some avg10=0.00 avg60=0.00 avg300=0.00 total=0
07-23 08:06:46.240 E/ActivityManager( 535): full avg10=0.00 avg60=0.00 avg300=0.00 total=0
07-23 08:06:46.240 E/ActivityManager( 535): ----- End output from /proc/pressure/memory -----
07-23 08:06:46.240 E/ActivityManager( 535):
07-23 08:06:46.240 E/ActivityManager( 535): CPU usage from 251334ms to 0ms ago (2025-07-23 08:02:33.912 to 2025-07-23 08:06:45.246):
07-23 08:06:46.240 E/ActivityManager( 535): 3.8% 293/android.hardware.bluetooth@1.1-service.sim: 0% user + 3.7% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 2.2% 27831/transport: 0% user + 2.1% kernel / faults: 123 minor
07-23 08:06:46.240 E/ActivityManager( 535): 1.8% 173/logd: 0% user + 1.8% kernel / faults: 38 minor
07-23 08:06:46.240 E/ActivityManager( 535): 1.5% 303/android.hardware.graphics.composer@2.3-service: 0% user + 1.5% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 1.1% 535/system_server: 0% user + 1% kernel / faults: 6016 minor
07-23 08:06:46.240 E/ActivityManager( 535): 0.7% 311/android.hardware.sensors@2.1-service.multihal: 0% user + 0.7% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 0.2% 372/adbd: 0% user + 0.2% kernel / faults: 1527 minor
07-23 08:06:46.240 E/ActivityManager( 535): 0.2% 324/surfaceflinger: 0% user + 0.2% kernel / faults: 168 minor
07-23 08:06:46.240 E/ActivityManager( 535): 0.1% 917/com.android.phone: 0% user + 0.1% kernel / faults: 319 minor
07-23 08:06:46.240 E/ActivityManager( 535): 0.1% 26886/process-tracker: 0% user + 0% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 0.1% 10/rcu_preempt: 0% user + 0.1% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 0% 291/android.hardware.audio.service.ranchu: 0% user + 0% kernel / faults: 15 minor
07-23 08:06:46.240 E/ActivityManager( 535): 0.1% 700/com.android.systemui: 0% user + 0.1% kernel / faults: 113 minor
07-23 08:06:46.240 E/ActivityManager( 535): 0.1% 27694/process-tracker: 0% user + 0% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 0% 29823/com.seven.memory: 0% user + 0% kernel / faults: 48 minor
07-23 08:06:46.240 E/ActivityManager( 535): 0% 302/android.hardware.graphics.allocator@3.0-service: 0% user + 0% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 0% 1076/com.android.launcher3: 0% user + 0% kernel / faults: 558 minor
07-23 08:06:46.240 E/ActivityManager( 535): 0% 1894/com.android.permissioncontroller: 0% user + 0% kernel / faults: 731 minor
07-23 08:06:46.240 E/ActivityManager( 535): 0% 420/audioserver: 0% user + 0% kernel / faults: 26 minor
07-23 08:06:46.240 E/ActivityManager( 535): 0% 26/ksoftirqd/3: 0% user + 0% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 0% 29549/installer: 0% user + 0% kernel / faults: 17843 minor
07-23 08:06:46.240 E/ActivityManager( 535): 0% 402/llkd: 0% user + 0% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 0% 16/ksoftirqd/1: 0% user + 0% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 0% 785/android.hardware.gnss@2.0-service.ranchu: 0% user + 0% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 0% 9/ksoftirqd/0: 0% user + 0% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 0% 21/ksoftirqd/2: 0% user + 0% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 0% 27685/logcat: 0% user + 0% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 0% 31/kauditd: 0% user + 0% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 0% 379/traced_probes: 0% user + 0% kernel / faults: 2 minor
07-23 08:06:46.240 E/ActivityManager( 535): 0% 29796/kworker/3:2-events_power_efficient: 0% user + 0% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 0% 30166/kworker/u8:2-events_unbound: 0% user + 0% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 0% 175/servicemanager: 0% user + 0% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 0% 205/jbd2/dm-5-8: 0% user + 0% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 0% 396/libgoldfish-rild: 0% user + 0% kernel / faults: 28 minor
07-23 08:06:46.240 E/ActivityManager( 535): 0% 176/hwservicemanager: 0% user + 0% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 0% 286/statsd: 0% user + 0% kernel / faults: 26 minor
07-23 08:06:46.240 E/ActivityManager( 535): 0% 288/zygote64: 0% user + 0% kernel / faults: 342 minor
07-23 08:06:46.240 E/ActivityManager( 535): 0% 388/iorapd: 0% user + 0% kernel / faults: 62 minor
07-23 08:06:46.240 E/ActivityManager( 535): 0% 29253/kworker/1:3-events: 0% user + 0% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 0% 1/init: 0% user + 0% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 0% 11/migration/0: 0% user + 0% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 0% 15/migration/1: 0% user + 0% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 0% 25/migration/3: 0% user + 0% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 0% 178/qemu-props: 0% user + 0% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 0% 209/android.system.suspend@1.0-service: 0% user + 0% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 0% 287/netd: 0% user + 0% kernel / faults: 2 minor
07-23 08:06:46.240 E/ActivityManager( 535): 0% 321/media.log: 0% user + 0% kernel / faults: 5 minor
07-23 08:06:46.240 E/ActivityManager( 535): 0% 380/traced: 0% user + 0% kernel / faults: 20 minor
07-23 08:06:46.240 E/ActivityManager( 535): 0% 387/installd: 0% user + 0% kernel / faults: 5 minor
07-23 08:06:46.240 E/ActivityManager( 535): 0% 401/android.hardware.biometrics.fingerprint@2.1-service: 0% user + 0% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 0% 676/wpa_supplicant: 0% user + 0% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 0% 1268/com.android.inputmethod.latin: 0% user + 0% kernel / faults: 3 minor
07-23 08:06:46.240 E/ActivityManager( 535): 0% 2173/com.android.keychain: 0% user + 0% kernel / faults: 34 minor
07-23 08:06:46.240 E/ActivityManager( 535): 0% 29672/kworker/2:0-mm_percpu_wq: 0% user + 0% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 0% 30072/kworker/u8:0-events_unbound: 0% user + 0% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 0% 30197/kworker/0:2-events: 0% user + 0% kernel
07-23 08:06:46.240 E/ActivityManager( 535): +0% 30354/kworker/0:1-events: 0% user + 0% kernel
07-23 08:06:46.240 E/ActivityManager( 535): +0% 30364/kworker/u8:1-events_unbound: 0% user + 0% kernel
07-23 08:06:46.240 E/ActivityManager( 535): +0% 30445/kworker/2:1-mm_percpu_wq: 0% user + 0% kernel
07-23 08:06:46.240 E/ActivityManager( 535): +0% 30448/install_server-08bc8eac: 0% user + 0% kernel
07-23 08:06:46.240 E/ActivityManager( 535): +0% 30467/com.seven.anr: 0% user + 0% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 1.8% TOTAL: 0% user + 1.8% kernel + 0% iowait + 0% softirq
07-23 08:06:46.240 E/ActivityManager( 535): CPU usage from 8ms to 254ms later (2025-07-23 08:06:45.254 to 2025-07-23 08:06:45.500):
07-23 08:06:46.240 E/ActivityManager( 535): 13% 535/system_server: 0% user + 13% kernel / faults: 202 minor
07-23 08:06:46.240 E/ActivityManager( 535): 13% 30503/AnrConsumer: 0% user + 13% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 4.1% 173/logd: 0% user + 4.1% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 4.1% 187/logd.auditd: 0% user + 4.1% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 4.2% 303/android.hardware.graphics.composer@2.3-service: 0% user + 4.2% kernel
07-23 08:06:46.240 E/ActivityManager( 535): 7.2% TOTAL: 0% user + 7.2% kernel
四.ANR的规避
我们知道anr主要是主线程中的耗时操作导致的,所以我们应当避免在主线程做耗时操作,尽量将耗时操作放到主线程中执行:
1.代码层面规避
1.将所有耗时操作如访问网络、socket 通信、查询大量 SQL 语句、复杂逻辑计算等都放在子线程中,然后通过 handler.sendMessage、runOnUIThread 等方式更新 UI。无论如何都要确保用户界面的流畅度,如果耗时操作需要让用户等待,可以在界面上显示进度条;
2.将 IO 操作放在异步线程。在一些同步的操作主线程有可能被锁,需要等待其他线程释放响应锁才能继续执行,这样会有一定的 ANR 风险,对于这种情况有时也可以用异步线程来执行相应的逻辑,另外,要避免死锁的发生,使用 Thread 或 HandlerThread 时,调用 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND)设置优先级,否则仍然会降低程序响应,因为默认 Thread 优先级和主线程相同,使用 Handler 处理工作线程结果,而不是使用 Thread.wait() 或 Thread.sleep() 来阻塞主线程;
3.Activity 的 onCreate() 和 onResume() 回调中避免耗时代码,BroadcastReceiver 中 onReceive() 代码也要尽量减少耗时,建议使用 IntentService 处理,各个组件的生命周期函数都不应该有太耗时的操作,即使对于后台 Service 或 ContentProvider 来讲,虽然应用在后台运行时生命周期函数不会有用户输入引起无响应的 ANR,但其执行时间过长也会引起 Service 或 ContentProvider 的 ANR。
2.增加检测机制
参考Android系统的WatchDog 的源码和原理自定义一个监控 ANR 的 WatchDog,事件 ANR 是 5s 无响应,那就设定每 5s 从 Looper 插一条消息,如果 5s 后还没执行完成就说明出现了 ANR
package com.seven.anr
import android.os.Handler
import android.os.Looper
import android.os.SystemClock
import android.util.Log
class ANRWatchDog private constructor(): Thread() {
private val mMainHandler: Handler = Handler(Looper.getMainLooper())
private val mAnrChecker: ANRChecker = ANRChecker()
private var mAnrListener: ANRListener? = null
private val lock=Object()
override fun run() {
// 设置为后台线程
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND)
while (true) {
synchronized(lock) {
// 开始计时,往主线程 Looper 插一条消息
mAnrChecker.schedule()
// 每 5s 循环一次
var waitTime = TIMEOUT.toLong()
val start = SystemClock.uptimeMillis()
while (waitTime > 0) { // 避免提前唤醒,保证 5s 检测一次
try {
lock.wait(waitTime)
} catch (e: InterruptedException) {
Log.w(TAG, e.toString())
}
waitTime =
TIMEOUT - (SystemClock.uptimeMillis() - start)
}
}
// 如果前面已经等待了超过了5秒,但是这里complete是true,进入下一次循环检测
if (!mAnrChecker.isBlocked) {
println("$TAG complete next start ${mAnrChecker.completed}")
continue
}
// 响应超过 5s ,complete未设置成true 认为已经发生了 ANR,将堆栈信息打印出来
val stackTrace = getStackTraceInfo()
if (mAnrListener != null) {
println("$TAG onAnrHappened")
mAnrListener!!.onAnrHappened(stackTrace)
}
mAnrListener = null
break
}
}
private fun getStackTraceInfo(): String {
val sb = StringBuilder()
for (element in Looper.getMainLooper().thread.stackTrace) {
sb.append(element.toString()).append("\r\n")
}
return sb.toString()
}
private inner class ANRChecker : Runnable {
var completed = false
private var startTime: Long = 0
private var executeTime = SystemClock.uptimeMillis()
override fun run() {
synchronized(lock) {
completed = true // 执行完修改标志位
executeTime = SystemClock.uptimeMillis()//执行时间
println("$TAG REC MSG--->> ")
}
}
fun schedule() {
println("$TAG REC START--->> ")
completed = false
startTime = SystemClock.uptimeMillis()
mMainHandler.postAtFrontOfQueue(this) // 往主线程 Looper 插入一条消息
}
val isBlocked: Boolean
// 如果标志位是 false 或响应时间超过 5s 返回true 表示未超过时间或者未完成 返回false表示
get() = !completed || executeTime - startTime >= TIMEOUT
}
fun setANRListener(listener: ANRListener?): ANRWatchDog {
println("$TAG setListener")
mAnrListener = listener
return this
}
interface ANRListener {
fun onAnrHappened(stackTrack: String?)
}
companion object {
private const val TAG = "ANRWatchDog"
private const val TIMEOUT = 5000
private var sWatchDog: ANRWatchDog? = null
val instance: ANRWatchDog?
get() {
if (sWatchDog == null) {
sWatchDog = ANRWatchDog()
}
return sWatchDog
}
}
}
ANRWatchDog.instance?.setANRListener(object :ANRWatchDog.ANRListener{
override fun onAnrHappened(stackTrack: String?) {
println("anr info:$stackTrack")
}
})?.start()
五.总结
anr的触发就是就是主线程的埋点因为各种各样的耗时操作,导致在规定的时间内埋点未被移除,从而导致无效应,我们应该尽量的将一些耗时操作放到子线程,避免产生anr,同时,当产生anr时,我们也可以通过日志和traces.txt来结合代码定位具体问题。