如何模拟Android主线程高负载触发ANR以开展代码测试?
如何模拟Android主线程高负载触发ANR以开展代码测试?
嘿,这个需求我太熟了!要模拟主线程高负载触发ANR其实挺简单的,给你几个实用的代码方案,都是我平时测试常用的:
死循环法(最直接粗暴):在主线程的某个触发点(比如按钮点击事件、Activity的
onCreate方法)里加个无限循环,直接把主线程完全占死,系统没法处理任何用户输入或后台消息,一般5秒左右就会触发ANR弹窗。
代码示例:// 比如在按钮点击事件中调用 public void triggerANRByLoop(View view) { while (true) { // 空循环,死死占用主线程资源 } }提醒下:这个方法触发后APP会彻底卡住,得手动强杀进程,测试完一定要记得删掉这段代码!
长时间睡眠法:利用
Thread.sleep()让主线程长时间阻塞,只要睡眠时长超过系统ANR的判定阈值(输入事件无响应的阈值是5秒),就能触发ANR。
代码示例:public void triggerANRBySleep(View view) { try { // 睡6秒,确保超过ANR阈值 Thread.sleep(6000); } catch (InterruptedException e) { e.printStackTrace(); } }这个方法和死循环效果类似,但逻辑更直观,适合快速验证ANR的触发流程。
密集计算法(贴近真实场景):如果想模拟业务中真实的高负载场景(比如复杂数据解析、大量UI计算导致的主线程阻塞),可以写一段密集的计算代码,把主线程的CPU占满。
代码示例:public void triggerANRByCalculation(View view) { long total = 0; // 执行亿级别的复杂计算,彻底占住主线程 for (long i = 0; i < 1000000000L; i++) { total += (i * i) + (i / 2) - (i % 3); } // 这里的日志大概率打不出来,因为主线程已经卡到无法处理日志输出了 Log.d("ANR_TEST", "计算完成:" + total); }
另外给你几个测试小提示:
- 尽量用真机测试,模拟器的ANR触发时间可能因为性能波动不太稳定;
- ANR触发后,系统会在设备的
/data/anr/目录生成traces.txt文件,你可以通过ADB命令拉取这个文件,分析主线程的堆栈信息,这也是你后续定位和处理ANR问题的核心依据; - 测试完毕后一定要清理掉这些模拟代码,绝对不能让它们出现在正式包中!
备注:内容来源于stack exchange,提问作者Bob Redity
相关产品推荐
相关产品推荐

