公司最近准备更换我们的第三方统计SDK
,由我负责集成到我们的项目当中。本篇文章是对集成过程出现的问题的一个总结。
产品简介
Bugly
是腾讯公司为移动开发者开放的服务之一,提供专业的异常上报,运营统计和内测分发解决方案,帮助开发者快速发现并解决异常,同时掌握产品运营动态,及时跟进用户反馈。
产品特点
- 重视Crash,能够实时掌控Crash,并快速修复。
- 多平台支持,
Android
,IOS
。 - 集成简单,文档可读性高。
同百度对比
相同点:
1、都可以统计
app
运营数据,使用的指标基本类似。如用户基本指标(新用户,留存用户,留存率,使用用户、启动次数、使用时长等等)
2、都可以上传Crash并归类分析。不同点
1、百度侧重于运营,有更多的运营数据,如对用户进行了更加精细的划分(用户属性,地域分析,使用分析,用户忠诚度等等)。百度还可以对自定义事件统计。
2、Bugly
侧重于Crash分析,可列出Crash全面出错信息,除了出错堆栈,还采集了丰富的出错时运行信息,并形成详细的可视化图表。运用高级搜索能够根据给定的
各种条件快速定位Crash。除了java
异常,同时还支持Android NDK
开发C/C++
类型的异常上报。
集成指南
- 注册产品,获取
App ID
注册成功后,打开产品设置页,可以找到对应的App Id
添加依赖
Bugly
支持JCenter
仓库和Maven Central
仓库。为了实现更加灵活的配置,Bugly SDK
(2.1.5及以上版本)和NDK(SO库)目前已经分开成两个独立的仓库:1
2SDK:com.tencent.bugly:crashreport
NDK:com.tencent.bugly:nativecrashrepor注意:集成
Bugly NDK
时,需要同时集成Bugly SDK
如果项目只需要统计Java层崩溃,那只需要单独集成
SDK
就可以了。1
2
3
4dependencies {
//其中latest.release指代最新Bugly SDK版本号,也可以指定明确的版本号,例如2.2.0
compile 'com.tencent.bugly:crashreport:latest.release'
}如果还需要统计Native层崩溃,还需要集成
NDK
。在项目的
App
模块下的build.gradle
文件中添加如下配置1
2
3
4
5
6
7
8
9
10
11
12
13android {
defaultConfig {
ndk {
// 设置支持的SO库架构
abiFilters 'armeabi' //, 'x86', 'armeabi-v7a', 'x86_64', 'arm64-v8a'
}
}
}
dependencies {
//其中latest.release指代最新Bugly NDK版本号,也可以指定明确的版本号,例如3.0
compile 'com.tencent.bugly:nativecrashreport:latest.release'
}如果在添加
abiFilter
之后Android Studio出现以下提示:1
NDK integration is deprecated in the current plugin. Consider trying the new experimental plugin.
解决办法:
在项目根目录的gradle.properties
文件中添加:1
android.useDeprecatedNdk=true
参数配置
权限配置
1
2
3
4
5<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_LOGS" />注:如果
App
需要上传到google play store
,需要将READ_PHONE_STATE
权限屏蔽掉或者移除,否则可能会被下架。混淆配置
如果项目开启了代码混淆,在Proguard
混淆文件中增加一行配置,因为集成的jar包已经做了一层混淆了:1
2-dontwarn com.tencent.bugly.**
-keep public class com.tencent.bugly.**{*;}
MultiDex
注意事项如果使用了
MultiDex
,建议通过Gradle
的multiDexKeepFile
配置等方式把Bugly
的类放到主Dex,另外建议在Application
类的attachBaseContext
方法中主动加载非主dex
:最简单的初始化
在项目的Application
类onCreate()
中,Bugly
会为自动检测环境并完成配置:1
CrashReport.initCrashReport(getApplicationContext(), "注册时申请的APPID", false);
第三个参数为
SDK
调试模式开关,调试模式的行为特性如下:- 输出详细的
Bugly SDK
的Log; - 每一条Crash都会被立即上报;
- 自定义日志将会在Logcat中输出。
建议在测试阶段建议设置成true,发布时设置为false。
- 输出详细的
增加上报进程控制
如果
App
使用了多进程且各个进程都会初始化Bugly
(例如在Application
类onCreate()
中初始化Bugly
),那么每个进程下的Bugly
都会进行数据上报,造成不必要的资源浪费。因此,为了节省流量、内存等资源,官方建议初始化的时候对上报进程进行控制,只在主进程下上报数据:判断是否是主进程(通过进程名是否为包名来判断),并在初始化
Bugly
时增加一个上报进程的策略配置。1
2
3
4
5
6
7
8
9
10Context context = getApplicationContext();
// 获取当前包名
String packageName = context.getPackageName();
// 获取当前进程名
String processName = getProcessName(android.os.Process.myPid());
// 设置上报的进程 这里是在主进程上报
UserStrategy strategy = new UserStrategy(context);
strategy.setUploadProcess(processName == null || processName.equals(packageName));
// 初始化Bugly
CrashReport.initCrashReport(context, "注册时申请的APPID", isDebug, strategy);测试
Bugly
是否生效在初始化
Bugly
的之后,主动制造一个空指针异常1
2Object object = null;
object.toString();执行到这段代码时会发生一个Crash,
Logcat
的TAG为CrashReportInfo
中输出为:在TAG=
CrashReport
能看到更多的堆栈相关信息,输出为:这些详细信息会被上传到
Bugly
管理的web页面,我们可以在管理页面去查看)
到这里Bugly
已经集成成功了
使用过程中的问题
Bugly
上报的Crash能区分测试环境和线上环境么?不能。只能通过注册产品的方式区分。就是测试环境的产品注册一个,线上环境的产品注册一个。
集成了
Bugly
后,需要只上报主进程产生的Crash,怎么做?最开始,我以为按照官方说的上面的
Bugly
上报进程控制的配置就ok了。但实际上经过自己的反复测试和与Bugly
官方人员沟通后,才明白上面的进程上报控制的配置的意思是,Bugly
会上报所有进程的Crash,但只会在主进程存在上报这个行为。所以,如果只是想上报主进程的Crash,那么就只在主进程初始化就可以了。为什么会有这样的需求呢?原因很简单,其他进程的Crash,并不会导致App
崩溃。而如果这些Crash都上报了,可能会导致Bugly
统计的Crash率过高,会被领导训。hahahaha发生Crash后,
Bugly
上报是即时的么?在管理页面看到实测可能会有几分钟的延迟。
需要定位到发生Crash的用户,怎么做?
Bugly
支持设置用户Id,因此可以在App
登陆后设置上UserId
,这样在bug管理页面就可以看到某个Crash的User Id了。1
CrashReport.setUserId("9527");
某些异常是我们比较关注的,想要主动上报,怎么做?
Bugly
已经提供了这样的API
1
2
3
4
5try {
//...
} catch (Throwable thr) {
CrashReport.postCatchedException(thr); // bugly会将这个throwable上报
}关于更多的
Bugly
配置,可以查看官方文档