admin 管理员组

文章数量: 887201

今天来写点Android崩溃的东西,在我们写代码的过程中,代码写的再好再严谨,也总是会有一些程序的崩溃,对于release出去的APP,我们肯定是希望我们能够拿到崩溃的日志,便于bug的发现以及修复,在下一个版本中再修复。所以,今天我们来说说Android崩溃日志的抓取。

在程序界面有一句话很流行,那就是不要重复造轮子。现在市面上有很多的崩溃日志抓取工具,比如腾讯的bugly,不管是eclipse还是Android Studio,集成都是非常简单,他可以抓取到JAVA的崩溃,同样也可以抓取到NDK代码的崩溃。

Java的崩溃就没有什么好说的,集成的步骤以及实现的原理太简单,下面我们来看看如何集成NDK崩溃的抓取

1、首先在c/c++代码的任意位置添加代码

const char SO_FILE_VERSION[]  __attribute__ ((section (".bugly_version"))) = "version name";

注意,如果是cpp文件得话必须加上extern "C",这一点腾讯给出来的文档里面没有说明。如果不加的话,我们编译出来的动态库是没有版本号信息的,为什么是.bugly_version,这个只有腾讯知道,我们知道腾讯定义了这个一个符号,用来读取出动态库的版本号来。

2、编译出so后,我们可以查看版本号,使用NDK工具arm-linux-androideabi-readelf.exe来读取。

命令行工具下运行arm-linux-androideabi-readelf.exe -p .bugly_version libXXXX.so就可以读取到第一步中写入的version name了。Windows系统arm-linux-androideabi-readelf.exe的路径为android-ndk-r10e\toolchains\arm-linux-androideabi-4.x\prebuilt\windows-x86_64\bin。

3、从编译结果的obj目录取出对应的动态库,利用腾讯提供的批处理文件生成map文件,并将map文件上传给腾讯,这样我们的apk里面发布的动态库是release版本的,但是通过腾讯的网页看到的堆栈还是可以定位到崩溃代码的行数以及所在的文件。

集成就这么结束了,还是很简单的,如下是我测试程序产生的崩溃日志

#00 pc 00000cd4 libErrorReport.so crash (E:/workspace/BuglyErrorTest/app/src/main/jni/ErrorReport.cpp:14-16) [armeabi-v5te] [1.0.1]

#01 pc 00000cdb libErrorReport.so Java_com_openflight_bugly_JniTest_nativeCrash (E:/workspace/BuglyErrorTest/app/src/main/jni/ErrorReport.cpp:21) [armeabi-v5te] [1.0.1]

#02 pc 000d3051  /data/dalvik-cache/arm/data@app@com.openflight.bugly-2@base.apk@classes.dex

bugly的集成就讲到这里了,那么问题来了,bugly是怎么做到的呢?以上都是基于我们的APP运行在有网络的环境下,那么如果我们开发的APP是要运行在一个没有网络的环境中呢,怎么办?怎么办?怎么办?很悲剧,本人是做车载导航开发的,而很多车载设备是没有网络的,那么就只能是抓取log保存在本地,然后取出对应的log来给开发人员分析了。JAVA的崩溃很好办,我们实现一下UncaughtExceptionHandler,然后将crash信息保存到本地的文件中就好了。那么NDK的崩溃呢?我们要感谢伟大的google把google-breakpad(https://github/svn2github/google-breakpad)开源出来了。

那接下来我们来看一下breakpad的集成吧。本例采用eclipse工程的方式,为啥不用Android Studio?因为breakpad给android提供的编译方式就是使用mk文件来编译的,而且个人感觉用eclipse来做NDK开发更方便。

先看一下jni目录的结构

本文标签: 日志 错误 文件 Android