海神平台是我们自主研发的一个移动端质量监控平台,从去年7月份开始至今,已陆续上线了Crash监控、ANR监控、网络监控、自定义错误等功能,目前已接入了公司内10余款APP(不区分Android和iOS平台)。本文将主要分享Android端在开发Crash监控SDK过程中的一些实践和经验。希望大家能有所收获。
一、Java层异常捕获
系统提供了一个钩子:Thread.setDefaultUncaughtExceptionHandler;
我们通过设置自定义的UncaughtExceptionHandler,就可以在崩溃发生的时候获取到现场信息。注意,这个钩子是针对单个进程而言的,在多进程的APP中,监控哪个进程,就需要在哪个进程中设置一遍ExceptionHandler。
// Thread.java
public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh)
public interface UncaughtExceptionHandler {
/**
* Method invoked when the given thread terminates due to the
* given uncaught exception.
* <p>Any exception thrown by this method will be ignored by the
* Java Virtual Machine.
* @param t the thread
* @param e the exception
*/
void uncaughtException(Thread t, Throwable e);
}
需要注意的是,在设置ExceptionHandler之前,要先通过get方法将之前的ExceptionHandler进行保存,然后在你消费完这次的崩溃信息后,需将崩溃传递给之前的ExceptionHandler。这样做的目的是在多个监控SDK并存时,每个监控SDK都能侦听到崩溃,系统默认的异常处理是直接退出进程。
为什么这个接口能捕获到Java层的所有崩溃?详见后续文章:《Android端DefaultUncaughtExceptionHandler异常捕获原理解读》
二、堆栈数据来源
- 2.1 从Throwable中我们可以获取以下信息:
Throwable ex
1)异常类型:ex.getClass().getName(); // 如"java.lang.ArithmeticException"
2)异常信息:ex.getLocalizedMessage(); // 如"divide by zero"
3)堆栈信息:ex.getStackTrace();// StackTraceElement[]
4)异常起因:ex.getCause(); // 创建该Throwable时的构造参数,也是一个Throwable,由此可以组成异常链
- 2.2 主线程的堆栈信息:
Looper.getMainLooper().getThread().get