android ANR源码分析 --- 之四
2017-10-31 20:21
751 查看
5,小结
Timeout时长对于前台服务,则超时为SERVICE_TIMEOUT = 20s;
对于后台服务,则超时为SERVICE_BACKGROUND_TIMEOUT = 200s
对于前台广播,则超时为BROADCAST_FG_TIMEOUT = 10s;
对于后台广播,则超时为BROADCAST_BG_TIMEOUT = 60s;
ContentProvider超时为CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10s;
按键事件为5s;
超时检测
Service超时检测机制:
超过一定时间没有执行完相应操作来触发移除延时消息,则会触发anr;
BroadcastReceiver超时检测机制:
有序广播的总执行时间超过 2* receiver个数 * timeout时长,则会触发anr;
有序广播的某一个receiver执行过程超过 timeout时长,则会触发anr;
另外:
对于Service, Broadcast, Input发生ANR之后,最终都会调用AMS.appNotResponding;
对于provider,在其进程启动时publish过程可能会出现ANR, 则会直接杀进程以及清理相应信息,而不会弹出ANR的对话框.
appNotRespondingViaProvider()过程会走appNotResponding(), 这个就不介绍了,很少使用,由用户自定义超时时间.
6,ANR处理
以下场景都会触发调用AMS.appNotResponding方法:1,ServiceTimeout:比如前台服务在20s内未执行完成;
2,BroadcastQueueTimeout:比如前台广播在10s内未执行完成
3,InputDispatchingTimeout: 输入事件分发超时5s,包括按键和触摸事件。
AMS的appNotResponding方法主要逻辑如下,
1, 输出ANR Reason信息到EventLog. 也就是说ANR触发的时间点最接近的就是EventLog中输出的am_anr信息;
updateCpuStatsNow(); //第一次 更新cpu统计信息
synchronized (this) {
//PowerManager.reboot() 会阻塞很长时间,因此忽略关机时的ANR
if (mShuttingDown) {
return;
} else if (app.notResponding) {
return;
} else if (app.crashing) {
return;
}
//记录ANR到EventLog
EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, app.processName, app.info.flags, annotation);
•••
2,收集并输出重要进程列表中的各个线程的traces信息,该方法较耗时;
//创建CPU tracker对象 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); //输出traces信息 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, NATIVE_STACKS_OF_INTEREST);
3, 输出当前各个进程的CPU使用情况以及CPU负载情况;
updateCpuStatsNow(); //第二次更新cpu统计信息 //记录当前各个进程的CPU使用情况 synchronized (mProcessCpuTracker) { cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); } //记录当前CPU负载情况 info.append(processCpuTracker.printCurrentLoad()); info.append(cpuInfo); //记录从anr时间开始的Cpu使用情况 info.append(processCpuTracker.printCurrentState(anrTime)); //输出当前ANR的reason,以及CPU使用率、负载信息 Slog.e(TAG, info.toString());
4, 将traces文件和 CPU使用情况信息保存到dropbox,即data/system/dropbox目录
//将traces文件 和 CPU使用率信息保存到dropbox,即data/system/dropbox目录 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, cpuInfo, tracesFile, null);
5, 根据进程类型,来决定直接后台杀掉,还是弹框告知用户.
synchronized (this) { ... //后台ANR的情况, 则直接杀掉 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { app.kill("bg anr", true); return; } ••• //弹出ANR对话框 Message msg = Message.obtain(); HashMap<String, Object> map = new HashMap<String, Object>(); msg.what = SHOW_NOT_RESPONDING_MSG; msg.obj = map; msg.arg1 = aboveSystem ? 1 : 0; map.put("app", app); if (activity != null) { map.put("activity", activity); } //向ui线程发送,内容为SHOW_NOT_RESPONDING_MSG的消息 mUiHandler.sendMessage(msg); }
可以看出,最后终于向ui线程发送内容为SHOW_NOT_RESPONDING_MSG的消息。
这样就是发生ANR时的弹出框。
相关文章推荐
- android-ANR源码分析
- Android 源码分析ANR
- 基于Android 6.0源码, 分析当发生ANR时系统的处理过程
- android ANR源码分析 --- 之一
- Android ANR源码原理分析
- android ANR源码分析 --- 之二
- 源码角度分析Android的事件输入系统(input system)及ANR原理分析
- Android应用层View绘制流程与源码分析
- android的消息处理机制(图+源码分析)——Looper,Handler,Message
- Android布局文件的加载过程分析:Activity.setContentView()源码分析
- Android:这是一份全面 &amp; 详细的Retrofit 2.0 源码分析指南
- Android 4.0 Launcher2源码分析——启动过程分析
- android源码解析(5)--AsyncTask源码分析以及使用中的坑
- Android—— View事件分发机制的源码分析
- 【Android 源码解析】从源码角度深入分析Handler消息机制
- Android源码分析之Fragment的View管理
- Android单元测试框架源码分析(三)构建自己的单元测试框架
- Android源码的层次结构分析
- Android源码分析-资源加载机制
- android adb 源码框架分析(5 客户端)