}
以上是广播结束者设置、解除、触发ANR的核心逻辑。通过handler机制延迟发送一个【ANR 任务】,在规定时间内完成了你广播接收者任务移除ANR任务。否则触发。
##### 1.2.1 系统处理ANR
实际无论何种条件触发了ANR最终都交给AnrHelper处理,这个类中核心处理ANR的逻辑开启一个名为“AnrConsumer”的线程。执行在ProcessErrorStateRecord中`appNotResponding()`的方法。
void appNotResponding(String activityShortComponentName, ApplicationInfo aInfo,
String parentShortComponentName, WindowProcessController parentProcess,
boolean aboveSystem, String annotation, boolean onlyDumpSelf) {
ArrayList firstPids = new ArrayList<>(5);
SparseArray lastPids = new SparseArray<>(20);
…
setNotResponding(true);//标记ANR标识
…
firstPids.add(pid);
…
isSilentAnr = isSilentAnr();//后台的应用发生ANR
if (!isSilentAnr && !onlyDumpSelf) {//前台进程和不仅仅dump自身时
mService.mProcessList.forEachLruProcessesLOSP(false, r -> {
…
firstPids.add(pid);//添加其他进程
}
});
…
StringBuilder report = new StringBuilder();
report.append(MemoryPressureUtil.currentPsiState());//内存信息
ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);//cup信息
nativePids.add(..); //添加native进程
...
File tracesFile = ..
report.append(tracesFileException.getBuffer());
info.append(processCpuTracker.printCurrentState(anrTime));
if (tracesFile == null) {
Process.sendSignal(pid, Process.SIGNAL_QUIT); //不dump信息时直接发送SIGNAL_QUIT信号
}
…
File tracesFile = ActivityManagerService.dumpStackTraces(…); //dump栈
…
mService.mUiHandler.sendMessageDelayed(msg, anrDialogDelayMs);//ANR弹窗
}
值得注意的点
* 沉默的ANR”,前台ANR会弹无响应的Dialog,后台ANR会直接杀死进程\*\*。
* dump信息时优先dump发生ANR进程的信息,条件允许dump其他关联进程和native进程。如果系统进程有很多ANR需要处理,且耗时已经超过60s或者是沉默进程就只会dump发生ANR进程信息
* dump全部进程的总时间不能超过20秒,如果超过了,马上返回,确保ANR弹窗可以及时的弹出(或者被kill掉)
* `Process.sendSignal(pid, Process.SIGNAL_QUIT);`系统会发出Process.SIGNAL\_QUIT信号。这个很重要

(图来自微信团队)
当应用发生ANR之后,系统会收集许多进程,来dump堆栈,从而生成ANR Trace文件,收集的第一个,也是一定会被收集到的进程,就是发生ANR的进程,接着系统开始向这些应用进程发送SIGQUIT信号,应用进程收到SIGQUIT后开始dump堆栈。
### 2 应用层怎么监控
Android M(6.0) 版本之后,应用侧不能直接通过监听