Bugly集成指南

公司最近准备更换我们的第三方统计SDK,由我负责集成到我们的项目当中。本篇文章是对集成过程出现的问题的一个总结。

产品简介

Bugly是腾讯公司为移动开发者开放的服务之一,提供专业的异常上报,运营统计和内测分发解决方案,帮助开发者快速发现并解决异常,同时掌握产品运营动态,及时跟进用户反馈。

产品特点

  • 重视Crash,能够实时掌控Crash,并快速修复。
  • 多平台支持,AndroidIOS
  • 集成简单,文档可读性高。

同百度对比

  • 相同点:

    1、都可以统计app运营数据,使用的指标基本类似。如用户基本指标(新用户,留存用户,留存率,使用用户、启动次数、使用时长等等)
    2、都可以上传Crash并归类分析。

  • 不同点
    1、百度侧重于运营,有更多的运营数据,如对用户进行了更加精细的划分(用户属性,地域分析,使用分析,用户忠诚度等等)。百度还可以对自定义事件统计。
    2、Bugly侧重于Crash分析,可列出Crash全面出错信息,除了出错堆栈,还采集了丰富的出错时运行信息,并形成详细的可视化图表。运用高级搜索能够根据给定的
    各种条件快速定位Crash。除了java异常,同时还支持Android NDK开发C/C++类型的异常上报。

集成指南

  1. 注册产品,获取App ID

1543483302186

注册成功后,打开产品设置页,可以找到对应的App Id

1543483964712

  1. 添加依赖

    Bugly支持JCenter仓库和Maven Central仓库。为了实现更加灵活的配置,Bugly SDK(2.1.5及以上版本)和NDK(SO库)目前已经分开成两个独立的仓库:

    1
    2
    SDK:com.tencent.bugly:crashreport
    NDK:com.tencent.bugly:nativecrashrepor

    注意:集成Bugly NDK时,需要同时集成Bugly SDK

    如果项目只需要统计Java层崩溃,那只需要单独集成SDK就可以了。

    1
    2
    3
    4
    dependencies {
    //其中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
    13
    android {
    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
  2. 参数配置

    • 权限配置

      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.**{*;}
  3. MultiDex注意事项

    如果使用了MultiDex,建议通过GradlemultiDexKeepFile配置等方式把Bugly的类放到主Dex,另外建议在Application类的attachBaseContext方法中主动加载非主dex

  4. 最简单的初始化
    在项目的ApplicationonCreate()中,Bugly会为自动检测环境并完成配置:

    1
    CrashReport.initCrashReport(getApplicationContext(), "注册时申请的APPID", false);

    第三个参数为SDK调试模式开关,调试模式的行为特性如下:

    • 输出详细的Bugly SDK的Log;
    • 每一条Crash都会被立即上报;
    • 自定义日志将会在Logcat中输出。

    建议在测试阶段建议设置成true,发布时设置为false。

  5. 增加上报进程控制

    如果App使用了多进程且各个进程都会初始化Bugly(例如在ApplicationonCreate()中初始化Bugly),那么每个进程下的Bugly都会进行数据上报,造成不必要的资源浪费。

    因此,为了节省流量、内存等资源,官方建议初始化的时候对上报进程进行控制,只在主进程下上报数据:判断是否是主进程(通过进程名是否为包名来判断),并在初始化Bugly时增加一个上报进程的策略配置。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Context 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);
  6. 测试Bugly是否生效

    在初始化Bugly的之后,主动制造一个空指针异常

    1
    2
    Object object = null;
    object.toString();

    执行到这段代码时会发生一个Crash,Logcat的TAG为CrashReportInfo中输出为:

    在TAG=CrashReport能看到更多的堆栈相关信息,输出为:

    这些详细信息会被上传到Bugly管理的web页面,我们可以在管理页面去查看

    1543492600424)
    到这里Bugly已经集成成功了

使用过程中的问题

  1. Bugly上报的Crash能区分测试环境和线上环境么?

    不能。只能通过注册产品的方式区分。就是测试环境的产品注册一个,线上环境的产品注册一个。

  2. 集成了Bugly后,需要只上报主进程产生的Crash,怎么做?

    最开始,我以为按照官方说的上面的Bugly上报进程控制的配置就ok了。但实际上经过自己的反复测试和与Bugly官方人员沟通后,才明白上面的进程上报控制的配置的意思是,Bugly会上报所有进程的Crash,但只会在主进程存在上报这个行为。所以,如果只是想上报主进程的Crash,那么就只在主进程初始化就可以了。为什么会有这样的需求呢?原因很简单,其他进程的Crash,并不会导致App崩溃。而如果这些Crash都上报了,可能会导致Bugly统计的Crash率过高,会被领导训。hahahaha

  3. 发生Crash后,Bugly上报是即时的么?

    在管理页面看到实测可能会有几分钟的延迟。

  4. 需要定位到发生Crash的用户,怎么做?

    Bugly支持设置用户Id,因此可以在App登陆后设置上UserId,这样在bug管理页面就可以看到某个Crash的User Id了。

    1
    CrashReport.setUserId("9527");
  5. 某些异常是我们比较关注的,想要主动上报,怎么做?

    Bugly已经提供了这样的API

    1
    2
    3
    4
    5
    try {
    //...
    } catch (Throwable thr) {
    CrashReport.postCatchedException(thr); // bugly会将这个throwable上报
    }

    关于更多的Bugly配置,可以查看官方文档