一、ANR机制框架与核心组件
在Android系统中,ANR(Application Not Responding)的监控和触发机制主要由ActivityManagerService(AMS)、InputManagerService(IMS)、BroadcastQueue等核心组件实现,依赖Binder通信和消息队列机制。以下是Framework层的核心流程:
二、ANR触发机制源码解析
1. 消息调度与超时检测
-
源码路径:
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java -
核心逻辑:
AMS通过Delayed Message机制监控组件响应时间。以Service为例,当服务启动时,AMS会发送延迟消息到主线程的Handler:
`// ActiveServices.java void scheduleServiceTimeoutLocked(ProcessRecord proc) { Message msg = mAm.mHandler.obtainMessage(ActivityManagerService.SERVICE_TIMEOUT_MSG); mAm.mHandler.sendMessageAtTime(msg, proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT); }`
若服务在20秒(前台)或200秒(后台)内未完成onStartCommand()等生命周期方法,AMS触发serviceTimeout()回调
2. Input事件超时
-
源码路径:
frameworks/base/services/core/java/com/android/server/input/InputManagerService.java -
关键流程:
输入事件通过InputDispatcher分发到应用进程,若主线程在5秒内未处理完毕,IMS会记录超时:`// InputDispatcher.cpp void processNextBroadcast() { // 设置超时时间点(当前时间+5秒) mAnrTime = now() + INPUT_DISPATCH_TIMEOUT_MS; // 若超时未完成,触发ANR if (mPendingEvent->deliveryTime > mAnrTime) { onAnrLocked(app); } }`超时后,系统通过
appNotResponding()方法收集进程堆栈和CPU信息
3. BroadcastReceiver超时
-
源码路径:
frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java -
实现细节:
广播处理通过processNextBroadcast()方法监控超时:`void processNextBroadcast(boolean fromMsg) { // 设置超时时间点(当前时间+10秒/60秒) final long timeoutTime = SystemClock.uptimeMillis() + (mQueue.mOrdered ? BROADCAST_TIMEOUT : 0); setBroadcastTimeoutLocked(timeoutTime); // 执行onReceive() performReceiveLocked(...); }`若前台广播超时10秒或后台广播超时60秒,AMS调用
broadcastTimeoutLocked()触发ANR
三、ANR触发后的处理流程
1. 堆栈与日志收集
-
核心方法:
ProcessRecord.appNotResponding()
该方法位于frameworks/base/services/core/java/com/android/server/am/ProcessRecord.java:`void appNotResponding(String activityShortComponentName, ...) { // 1. 生成traces.txt File tracesFile = ActivityManagerService.dumpStackTraces(pid, ...); // 2. 记录CPU使用情况 mService.updateCpuStatsNow(); // 3. 弹出ANR对话框 if (showBackground) { mService.mUiHandler.sendMessage(Message.obtain(...)); } }`2. ANR对话框显示
-
源码路径:
frameworks/base/services/core/java/com/android/server/am/AppNotRespondingDialog.java -
触发条件:
仅当应用处于前台时显示对话框,后台ANR默认不提示(通过Settings.Secure.ANR_SHOW_BACKGROUND配置)
四、系统级监控架构
1. Watchdog机制
-
实现类:
frameworks/base/services/core/java/com/android/server/Watchdog.java -
作用:
监控SystemServer进程是否阻塞,若HandlerThread未按时处理消息,触发系统级ANR(SNR)
2. Binder通信监控
-
关键点:
Binder调用超时(默认30秒)可能引发ANR。AMS通过Binder.setDumpTimeout()设置跨进程调用的最大等待时间:`// Binder.java public static void setDumpTimeout(IBinder binder, long timeoutMillis) { nativeSetDumpTimeout(binder, timeoutMillis); }`若服务端未及时响应,客户端触发
TransactionTooLargeException或ANR
五、优化与调试建议
-
主线程监控:
使用StrictMode检测主线程IO和网络操作:`StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .detectDiskReads().detectNetwork().penaltyLog().build());`2. 异步任务管理:
通过HandlerThread或ExecutorService分离耗时操作,避免阻塞主线程 -
ANR日志分析工具:
- Systrace:追踪主线程消息队列阻塞点
- Perfetto:分析CPU调度和Binder调用链
- adb命令:
adb bugreport导出完整的ANR日志
六、总结
ANR机制本质是多维度超时检测系统,其核心在于:
- 消息调度延迟检测(AMS的Delayed Message)
- 输入事件分发监控(IMS的InputDispatcher)
- 跨进程通信超时管理(Binder线程池)
通过分析ProcessRecord和ActiveServices等关键类,开发者可深入理解ANR触发逻辑,优化应用响应性能。