在 Android 中,应用崩溃可以分为四种,分别是:Java崩溃、native崩溃、ANR、OOM
- Java崩溃:就是在Java代码中,出现了未捕获异常,导致程序异常退出
- Native崩溃:发生在 native 层面的崩溃,一般都是因为在Native代码中访问非法地址,也可能是地址对齐出现了问题,或者发生了程序主动abort,这些都会产生相应的signal信号,导致程序异常退出。
- ANR:应用无响应。当事件输入是5s、广播10s,前台服务20s,后台服务200s无响应时,弹出应用无响应的dialog。
- oom: 是指内存溢出导致的应用崩溃
Java崩溃
Java 层面的崩溃,常见的主要有空指针异常(NullPointerException)、数组越界异常(ArrayIndexOutOfBoundsException)、类型转换异常(ClassCastException)、算术异常(ArithmeticException)等
在线下环境我们在开发应用时,出现了java层面的崩溃,可以通过logcat的堆栈信息 和 debug 的方式来找出原因。但是到了线上环境,上面方法就不可用了。
这时我们可以实现 Thread.UncaughtExceptionHandler
接口,通过Thread.setDefaultUncaughtExceptionHandler
来将异常信息上传到服务器。或者使用 Firebase Crashlytics 和 Bugly 等平台来获取崩溃信息。
native 崩溃
对于 native的崩溃 ,我们需要使用 Google 的 Breakpad库,它的功能主要是采集 native 的crash日志。关于Breakpad的使用,可以看 Google Breakpad Android 使用详解。当前我们也可以直接使用 Bugly、啄木鸟 等平台来处理native的崩溃
ANR
应用发生ANR时,会将ANR的信息写入/data/anr/下生成对应的ANR异常信息的文件。
在线下环境,我们可以使用Android studio的文件查看工具直接查看或者使用adb pull /data/anr/traces.txt [目标路径]
命令导出。高版本的os上如果权限不足,则可以通过chmod来修改该文件的权限(手机root的情况下)。线上环境,建议是使用Bugly、啄木鸟 等平台来获取对应的日志信息。
获取到 anr日志 后,先看看主线程的堆栈,是否是因为锁等待导致。接着看看ANR日志中iowait、CPU、GC、system server等信息,进一步确定是I/O问题,或是CPU竞争问题,还是由于大量GC导致卡死
OOM
OOM 主要是由内存泄漏造成的。分析内存泄露的功能有很多,常用的有 LeakCanary、Memory Analyzer(MAT)、Memory Profiler等,适用于线下发现内存泄露问题。对于线上,还是推荐使用Bugly、啄木鸟 等平台