5.1 handleAppCrashInActivityController
handleAppCrashInActivityController,通过IActivityController 实例导致的Crash , 则不显示弹窗.
AppError.java
private boolean handleAppCrashInActivityController(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo, String shortMsg, String longMsg, String stackTrace, long timeMillis, int callingPid, int callingUid) { ... ...// 当存在ActivityController的情况,比如monkey try { String name = r != null ? r.processName : null; int pid = r != null ? r.pid : callingPid; int uid = r != null ? r.info.uid : callingUid; //调用monkey的 appCrashed if (!mService.mController.appCrashed(name, pid, shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) && "Native crash".equals(crashInfo.exceptionClassName)) { Slog.w(TAG, "Skip killing native crashed app " + name + "(" + pid + ") during testing"); } else { Slog.w(TAG, "Force-killing crashed app " + name + " at watcher's request"); if (r != null) { //调用`makeAppCrashingLocked` , 继续处理crash流程 // 详见 小结 6if (!makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace, null)) { r.kill("crash", true); } } else { // Huh. Process.killProcess(pid); ActivityManagerService.killProcessGroup(uid, pid); } } return true; } } catch (RemoteException e) { mService.mController = null; Watchdog.getInstance().setActivityController(null); } return false; }该方法主要做的两件事:
- 调用makeAppCrashingLocked , 继续处理Crash流程;
- 发送消息SHOW_ERROR_MSG , 弹出提示Crash的对话框 , 等待用户选择;
接下来我们看makeAppCrashingLocked实现 。
private boolean makeAppCrashingLocked(ProcessRecord app, String shortMsg, String longMsg, String stackTrace, AppErrorDialog.Data data) { app.crashing = true; //封装crash信息到crashingReport对象 app.crashingReport = generateProcessError(app, ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); //【见小节7】 startAppProblemLocked(app); //停止屏幕冻结【见小节8】 app.stopFreezingAllLocked(); //【见小节9】 return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace, data); }七、startAppProblemLocked处理分析AppError.java
startAppProblemLocked 该方法主要功能:
- 获取当前用户下的crash应用的error receiver;
- 忽略当前App的广播接收;
ApplicationErrorReport.java
获取当前用户下的Crash应用的error receiver
public static ComponentName getErrorReportReceiver(Context context, String packageName, int appFlags) { //检查Settings中的"send_action_app_error"是否使能错误报告的功能 int enabled = Settings.Global.getInt(context.getContentResolver(), Settings.Global.SEND_ACTION_APP_ERROR, 0); if (enabled == 0) { //1.当未使能时 , 则直接返回 return null; } PackageManager pm = context.getPackageManager(); // look for receiver in the installer package String candidate = null; ComponentName result = null; try { //获取该crash应用的安装器的包名 candidate = pm.getInstallerPackageName(packageName); } catch (IllegalArgumentException e) { // the package could already removed } if (candidate != null) { result = getErrorReportReceiver(pm, packageName, candidate); if (result != null) { //2.当找到该crash应用的安装器 , 则返回; return result; } } //该系统属性名为"ro.error.receiver.system.apps" if ((appFlags&ApplicationInfo.FLAG_SYSTEM) != 0) { candidate = SystemProperties.get(SYSTEM_APPS_ERROR_RECEIVER_PROPERTY); // 通过上下文对象传参 , 调用类内部方法 result = getErrorReportReceiver(pm, packageName, candidate); if (result != null) { //3.当crash应用是系统应用时 , 且系统属性指定error receiver时 , 则返回; return result; } } //该默认属性名为"ro.error.receiver.default" candidate = SystemProperties.get(DEFAULT_ERROR_RECEIVER_PROPERTY); //4.当默认属性值指定error receiver时 , 则返回; return getErrorReportReceiver(pm, packageName, candidate); }getErrorReportReceiver:这是同名不同输入参数的另一个方法:
推荐阅读
- 几款实用的Android Studio 插件给你推荐一下
- Android Studio Debug 的 9 个小技巧
- JavaScript 中对于Promise的理解
- 在 Linux 上用 strace 来理解系统调用
- 深入理解Java继承的实现原理
- android Flutter 工程结构和资源文件分辨率相关的图片文件放哪儿
- 现象学家所理解的现象 世界上科学家无法解释的现象
- 800 字彻底理解 Go语言 指针
- HDFS架构详解!会了这个,hadoop还难理解吗?
- 如何深入浅出理解数据仓库建模?