Firebase Crashlytics Sdk接入流程

Firebase Crashlytics是收购了Fabric而来的,服务器也是Fabric的,所以虽然Firebase中很多功能在国内是不能用的,但是 Crashlytics 这个功能却是可以用的。 大家可以放心的使用Firebase来做Crash统计分析。

考拉刚刚把crash统计平台迁移到了firebase上,在此记录一下接入Firebase Crashlytics Sdk的流程,以供大家参考。

接入一个新的SDK,最重要的文档就是官方手册,Firebase Crashlytics的官方手册是这个Firebase Crashlytics 使用入门 | Firebase,一定要注意看的是Crashlytics的文档,而不是“Firebase 崩溃报告(Firebase Crash Reporting)”,后者是firebase已经不维护的产品。

步骤一 接入Firebase

Crashlytics作为Firebase的一部分,要使用Crashlytics必须先接入Firebase。

官方文档写明的步骤本文就不再重复了,这部分的官方文档链接如下,请点击链接阅读。
将 Firebase 添加到您的 Android 项目 | Firebase

可选择使用Firebase Assistant自动配置和手动接入Firebase两种方式,推荐先尝试Firebase 智能助理自动配置,如果不能自动配置成功,再尝试手动配置。

上面按照官方文档的操作的步骤中,如果使用Firebase Assistant 要注意一定不要选“Crash Reporting”,这是firebase已经废弃的服务,然而现在新的Crashlytics却不在Assistant列表内。这一步就选Analytics就好了,不用担心选了Analytics多了冗余的依赖,使用Firebase的任何服务都要先依赖Analytics,Analytics是必需的依赖。

另外即使使用了Firebase Assistant 也建议看一遍手动添加的步骤,然后检查一下Firebase 智能助理自动生成的代码是否与手动添加的代码一致,不能完全依赖工具。

这一步完成后,当前下项目的代码情况应该是这样的:

  • 工程级 build.gradle 文件
buildscript {    // ...    dependencies {        // ...        classpath 'com.google.gms:google-services:4.1.0' // google-services plugin    }}allprojects {    // ...    repositories {        // ...        google() // Google's Maven repository    }}
  • application级 build.gradle文件(通常是 app/build.gradle)
apply plugin: 'com.android.application'android {  // ...}dependencies {  // ...  implementation 'com.google.firebase:firebase-core:16.0.4'  // Getting a "Could not find" error? Make sure you have  // added the Google maven respository to your root build.gradle}// ADD THIS AT THE BOTTOMapply plugin: 'com.google.gms.google-services'
  • google-services.json文件一定要放在application级 build.gradle(通常是 app/build.gradle)同级目录下
.├── app│   ├── build.gradle│   ├── google-services.json│   └── src├── build.gradle├── gradle.properties├── local.properties└── settings.gradle

此时可以sync一遍gradle依赖,运行一下你的app,如果在应用启动时出现如下log
I/FirebaseInitProvider: FirebaseApp initialization successful
则表示,app正常接入了,接下来,就该接入Crashlytics了。

步骤二 Crashlytics SDK接入

如果你之前的项目使用的是Fabric Crashlytics,那你可以直接使用[Fabric迁移流程](https://fabric.io/firebase_migration)来快速迁移到Firebase Crashlytics。否则,请继续看下面的步骤。

首先点击Firebase 控制台中的 Crashlytics按钮来开启Crashlytics服务。

  • 然后,在项目级 build.gradle 中,添加 Crashlytics 代码库和依赖项
buildscript {    repositories {        // ...        // Add repository        maven {           url 'https://maven.fabric.io/public'        }    }    dependencies {        // ...        // Check for v3.1.2 or higher        classpath 'com.google.gms:google-services:4.1.0'        // Add dependency        classpath 'io.fabric.tools:gradle:1.26.1'    }}allprojects {    // ...    repositories {       // ...       // Add repository       maven {           url 'https://maven.google.com/'       }    }}
  • 在应用级 build.gradle 中,添加 Crashlytics 相关配置
apply plugin: 'com.android.application'apply plugin: 'io.fabric'dependencies {    // ...    // Check for v11.4.2 or higher    implementation 'com.google.firebase:firebase-core:16.0.6'    // Add dependency    implementation 'com.crashlytics.sdk.android:crashlytics:2.9.8'}

做完这一步后,就可以启动app并制造一个crash,到Firebase 控制台中的 Crashlytics页面查看是否有数据上报即可。Firebase的数据上报实时性很高,尤其是新建的项目,数据量很少,出现crash后几秒钟就能在Firebase Crashlytics的平台上看到了。

建议在debug模式下添加 ext.alwaysUpdateBuildId = false标志来阻止 Crashlytics 不断更新其构建 ID,优化日常开发的编译速度。

android {  ...  buildTypes {    debug {      ext.alwaysUpdateBuildId = false    }}

步骤三 (可选) Crashlytics SDK NDK Crash监控

Firebase Crashlytics的官方文档只列出来了Java代码的Crash监控使用方式,并没有提及NDK Crash的监控。
对于大部分Android开发者来说,NDK的Crash也确实没有监控的必要,但是考拉这边用了很多第三方so库,这些so库也是有必要监控起来的。
Firebase Crashlytics是由Firebase收购Fabric而来的项目,技术方案也几乎没有变化,所以可以用Fabric监控NDK Crash的使用方式使用Firebase Crashlytics。
Fabric NDK Crash Reporting

  • 在应用级 build.gradle 中,添加 Crashlytics NDK Crash Reporting 相关配置
apply plugin: 'com.android.application'apply plugin: 'io.fabric'// set NDK Crash Reporting enablecrashlytics {    enableNdk true}dependencies {    // ...    implementation 'com.google.firebase:firebase-core:16.0.6'    implementation 'com.crashlytics.sdk.android:crashlytics:2.9.8'    // Add ndk dependency    implementation 'com.crashlytics.sdk.android:crashlytics-ndk:2.0.5'}

在manifest中声明Crashlytics手动初始化

        

根据自身app启动流程,选择合适时机手动初始化Crashlytics

   Fabric.with(context, new Crashlytics(), new CrashlyticsNdk());

如果是本地源码编译的so而不是直接使用第三方提供的so,可以生成并上传符号表来辅助分析crash信息,执行 ./gradlew crashlyticsUploadSymbolsRelease即可上传符号表。

以上,就完成了Crashlytics SDK NDK Crash监控的配置,可以手动引发一个Ndk Crash来测试,到统计平台上看是否有对于的Crash。

打包NDK代码引发native crash比较麻烦,在此提供一个从java代码引发NDK Crash的方式:

 public void crashNatively() {        try {            Class.forName("dalvik.system.VMDebug").getMethod("crash").invoke(null);        } catch (Exception e) {            e.printStackTrace();        }    }

步骤四 添加辅助数据帮助分析

通过以上步骤的配置,现在Firebase Crashlytics已经可以正常工作了。并且还附带了发生Crash的时间,机型,系统版本,应用版本等信息以供分析。

然而实际使用过程中,我们都期望能得到更详细的用户信息,这时可以自定义添加更多数据,下面是一些考拉中添加的一些常用信息。

//用户idCrashlytics.setUserIdentifier(builder.getUserId());//用户渠道Crashlytics.setString("Channel", builder.getChannelInfo());//用户补丁版本Crashlytics.setString("Version", builder.getUserTag());//用户当前WebView UACrashlytics.setString("WebView UA", WebViewSettings.getUserAgent());//打包机名称Crashlytics.setString("BuildHost", BuildInfo.BUILD_HOST);//打包时间Crashlytics.setString("BuildTime", BuildInfo.BUILD_TIME);//最新提交commit idCrashlytics.setString("GitLog", BuildInfo.BUILD_GIT_LOG);         

这些自定义的数据可以在,Firebase Crashlytics的“键”选项卡下面看到。

通过setUserIdentifier所设置的用户Id还可以用于搜索。

还可以通过Crashlytics.log方法,打入自定义日志用于分析。

开发过程中,还会遇到通过try catch捕获了异常,不造成崩溃,但是又希望能够统计上报该异常的情况。这个时候,可以使用Crashlytics.logException(throwable)方法将异常统计上来。
在Firebase的过滤条件中选择,不严重的事件类型,即可过滤该异常。

步骤五 修改ProGuard混淆规则

参考官方文档 获取经过反混淆处理的崩溃报告 配置即可。

-keepattributes *Annotation*-keepattributes SourceFile,LineNumberTable-keep public class * extends java.lang.Exception-keep class com.crashlytics.** { *; }-dontwarn com.crashlytics.**// 删除-printmapping mapping.txt 这一行// -printmapping mapping.txt

步骤六(可选) oppo部分机型谷歌服务框架弹框优化

做完以上所有步骤,基本就可以上线了。但是实际使用中发现,有用户反馈在oppo手机上会提示需要先下载谷歌服务框架才能运行。按照oppo手机的提示操作,下载好谷歌服务框架就能正常使用。
这个现象有些影响用户体验,虽然实际出现这个现象的手机是极少数(找了很多天,才在一台旧版的oppo A53m上复现了这个问题,怀疑是oppo旧版系统并且很久没有更新过才会出现),但是秉着提升用户体验的角度,还是专门做了优化。

这个弹框是这样的。

一般这种问题,只要在这种手机上,关掉crash分析即可。
然而在出现这个弹框后,app无法得到任何通知,就直接被oppo系统杀掉了,并且也找不到可靠的途径来判断是否会弹这个框。
经过一番debug加测试,基本确定,是有Activity变化的时候,会触发Firebase的统计上报功能,这时会触发com.google.android.gms.measurement.AppMeasurementReceiver这个Receiver,然后触发com.google.android.gms.measurement.AppMeasurementService这个service,然后调用gms上传数据到服务器。国内手机一般都没有gms框架,正常情况下这里发现没有gms的时候,就会走Firebase SDK内置的应用内上传逻辑。但是oppo手机比较奇怪,它应该是内置了gms上传事件的接收器,然而这个接收器的作用,不是上传数据,而是把app进程杀死,然后弹个窗(我也是醉了)。

看起来app是无法对这个现象做任何处理了,即使是通过机型来做黑名单,都不能很好的判断,毕竟即使是同一个机型,也仅有极少数会出现这个弹框,存在很大的误伤概率。
这种情况下,只剩下了一种办法,先让这个现象出现,然后下次启动时再通过上次是否出现了这个现象,来规避问题。虽然会至少出现一次不友好现象,但至少比用户一直不下载谷歌服务框架就一直出现弹窗要好一些。

新建了一个Int类型SharePreference值,默认是0,当app第一次启动的时候,设为-1,MainActivity启动成功后,设为1。
这样,下次启动时,如果发现没有这个SharePreference值为-1,则表示上次没有成功启动,就关闭Firebase。
这里的关闭还有些特殊,直接不初始化Firebase的话,会完全失去Crash监控效果,我们只把AppMeasurementReceiver这个Receiver diasble,这样只是失去了用户信息上报,少了些log和轻微影响数据百分比准确度,不影响正常crash上报功能,最大程度保留了功能完整性。

int activityInitSuccessFlag = PreferencesUtils.getInt(CrashCollector.ACTIVITY_INIT_SUCCESS_FLAG, 0);                        if (activityInitSuccessFlag == 0) {                            PreferencesUtils.saveInt(CrashCollector.ACTIVITY_INIT_SUCCESS_FLAG, -1);                            CrashCollector.setGmsReceiverEnable(getApplication(), true);                        } else if (activityInitSuccessFlag == 1) {                            CrashCollector.setGmsReceiverEnable(getApplication(), true);                        } else if (activityInitSuccessFlag == -1) {                            CrashCollector.setGmsReceiverEnable(getApplication(), false);                        }
    private void MainActivityInitSuccess() {        if (CrashCollector.sGmsReceiverEnableEnable) {            PreferencesUtils.saveInt(CrashCollector.ACTIVITY_INIT_SUCCESS_FLAG, 1);        }    }
    public static void setGmsReceiverEnable(Context context, boolean enable) {        sGmsReceiverEnableEnable = enable;        PackageManager pm = context.getApplicationContext().getPackageManager();        ComponentName componentName = new ComponentName(context.getPackageName(),                "com.google.android.gms.measurement.AppMeasurementReceiver");        int state = enable ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED                : PackageManager.COMPONENT_ENABLED_STATE_DISABLED;        pm.setComponentEnabledSetting(componentName, state, PackageManager.DONT_KILL_APP);    }

以上,就是全部Firebase Crashlytics的接入步骤,以供参考。

引用:

  1. Firebase Crashlytics 使用入门 | Firebase
  2. 将 Firebase 添加到您的 Android 项目 | Firebase
  3. Fabric NDK Crash Reporting
  4. 获取经过反混淆处理的崩溃报告

更多相关文章

  1. Android(安卓)穿山甲广告接入注意事项
  2. Android(安卓)studio 一直卡在Gradle:Build Running
  3. Intellij Idea gradle Android(安卓)depends Setting
  4. android一键退出
  5. Android(安卓)Studio 引用jar和so 文件
  6. android标题栏添加延时加载标志
  7. Android控件RecyclerView和ListView的异同
  8. Android(安卓)framework/base 下添加新的接口
  9. Android(安卓)状态栏下拉列表添加自定义item开关

随机推荐

  1. 在Android中查看和管理sqlite数据库
  2. Android异步消息处理机制Handler完全解析
  3. Android异步处理三:Handler+Looper+Messag
  4. Android(安卓)开发学习 HelloAndroid例子
  5. Delphi XE5的Android开发平台搭建
  6. Android(安卓)开发学习 HelloAndroid例子
  7. 项目中遇到的问题留下笔记
  8. Ubuntu 下 Android源代码下载指南
  9. 如何判断Android系统的版本
  10. 详解谷歌官方教程 Android插件ADT 9.0.0