- 1.当System进程Crash的信息:
- 2.当app进程Crash时的信息:
看到这里 , 你就会发现要从log中搜索Crash信息 , 只需要搜索关键词 FATAL EXCEPTION,即可查看出是那种异常;如果需要进一步筛选只搜索系统crash信息 , 则可以搜索的关键词可以有多样 , 比如 FATAL EXCEPTION IN SYSTEM PROCESS 。
当输出完Crash信息到logcat里面 , 这只是Crash流程的刚开始阶段 , 接下来弹出Crash对话框 , ActivityManagerNative.getDefault()返回的是ActivityManagerProxy(简称AMP) , AMP经过binder调用最终交给ActivityManagerService(简称AMS)中相应的方法去处理,然后调用的是AMS.handleApplicationCrash() 。
分析完LoggingHandler后 , 我们继续看setDefaultUncaughtExceptionHandler() , 它只是将异常处理器handler对象赋给Thread成员变量,即Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler(loggingHandler)); 。接下来看看KillApplicationHandler对象实例化过程 。
2. KillApplicationHandler
RuntimeInit.java
KillApplicationHandler 实现 Thread.UncaughtExceptionHandler方法,主要处理由于未捕获的异常Crash导致APP 崩溃,运行在Main Thread的Framework 代码会捕获这些异常 。
KillApplicationHandler 方法需要传递一个LoggingHandler的参数 ,
既 LoggingHandler loggingHandler = new LoggingHandler(); , LoggingHandler在上文已经分析过 , 接下来我们看看KillApplicationHandler方法.
KillApplicationHandler方法如下:
private static class KillApplicationHandler implements Thread.UncaughtExceptionHandler { private final LoggingHandler mLoggingHandler; public KillApplicationHandler(LoggingHandler loggingHandler) { // 构造方法 , 初始化 loggingHandlerthis.mLoggingHandler = Objects.requireNonNull(loggingHandler); } @Override public void uncaughtException(Thread t, Throwable e) { try { ensureLogging(t, e); // 保证crash处理过程不会重入 if (mCrashing) return; mCrashing = true; ... ... //启动crash对话框 , 等待处理完成 【见小节2.1和3】 ActivityManager.getService().handleApplicationCrash( mApplicationObject, new ApplicationErrorReport.ParcelableCrashInfo(e)); } catch (Throwable t2) { ... ...} finally { //确保当前进程彻底杀掉【见小节11】 Process.killProcess(Process.myPid()); System.exit(10); } } ... ...}接下来我们看看启动Crash弹窗的处理 。new ApplicationErrorReport.ParcelableCrashInfo(e)方法 。
2.1 ApplicationErrorReport.ParcelableCrashInfo
ApplicationErrorReport 主要用来描述 APP Error信息 。
APP ERROR 信息分类如下:
- TYPE_CRASH: APP Crash 信息
- TYPE_ANR: APP ANR 信息
- TYPE_BATTERY: Battery 使用信息
- TYPE_RUNNING_SERVICE: 正在运行的Service 相关信息
CrashInfo
**CrashInfo ** 主要是将Crash信息文件名 , 类名 , 方法名 , 对应行号以及异常信息都封装到CrashInfo对象 。
// 描述 Crash 信息 public static class CrashInfo { ... ... public CrashInfo() { } //CrashInfo 初始化实例public CrashInfo(Throwable tr) { StringWriter sw = new StringWriter(); PrintWriter pw = new FastPrintWriter(sw, false, 256); //输出栈trace tr.printStackTrace(pw); pw.flush(); stackTrace = sanitizeString(sw.toString()); exceptionMessage = tr.getMessage(); // 显示异常的根本原因 Throwable rootTr = tr; while (tr.getCause() != null) { tr = tr.getCause(); if (tr.getStackTrace() != null && tr.getStackTrace().length > 0) { rootTr = tr; } String msg = tr.getMessage(); if (msg != null && msg.length() > 0) { exceptionMessage = msg; } } // Crash 异常类名称exceptionClassName = rootTr.getClass().getName(); if (rootTr.getStackTrace().length > 0) { StackTraceElement trace = rootTr.getStackTrace()[0]; // 获取 trace 文件名、类名、方法名、Crash 行号 throwFileName = trace.getFileName(); throwClassName = trace.getClassName(); throwMethodName = trace.getMethodName(); throwLineNumber = trace.getLineNumber(); } else { throwFileName = "unknown"; ... ...} exceptionMessage = sanitizeString(exceptionMessage); }
推荐阅读
- 几款实用的Android Studio 插件给你推荐一下
- Android Studio Debug 的 9 个小技巧
- JavaScript 中对于Promise的理解
- 在 Linux 上用 strace 来理解系统调用
- 深入理解Java继承的实现原理
- android Flutter 工程结构和资源文件分辨率相关的图片文件放哪儿
- 现象学家所理解的现象 世界上科学家无法解释的现象
- 800 字彻底理解 Go语言 指针
- HDFS架构详解!会了这个,hadoop还难理解吗?
- 如何深入浅出理解数据仓库建模?