如何在开发过程中禁用Crashlytics

270

在开发过程中有没有简单的方法可以关闭Crashlytics Android SDK?

我不想每次做傻事都发送一份崩溃报告。

另一方面,我也不想注释掉Crashlytics.start() ,可能会忘记取消注释并提交代码。


你尝试过从清单中删除API密钥吗?我不记得那是否会导致崩溃。 - Timmetje
@timmied 它会崩溃。在“清单”中注释整行也会导致应用程序崩溃,因此这使问题更加合法。 - Michael
31个回答

399

我从Crashlytics(与Fabric集成)中找到了解决方案。

将以下代码放在您的Application类的onCreate()方法中:

Crashlytics crashlytics = new Crashlytics.Builder().disabled(BuildConfig.DEBUG).build();
Fabric.with(this, crashlytics);

编辑:

在 Crashalitics 2.3 及以上版本中,此方法已被弃用。正确的代码应为:

CrashlyticsCore core = new CrashlyticsCore.Builder().disabled(BuildConfig.DEBUG).build();
Fabric.with(this, new Crashlytics.Builder().core(core).build());
或者
Fabric.with(this, new Crashlytics.Builder().core(new CrashlyticsCore.Builder().disabled(BuildConfig.DEBUG).build()).build());

(来自Crashlytics已弃用的disabled()方法)


编辑2:

您还可以选择将此命令添加到gradle中的buildType。 此命令禁用发送crashlytics映射文件并为每个构建生成ID,从而加快这些flavor的gradle构建速度。(它不会在运行时禁用Crashlytics。) 请参阅Mike B的答案。

buildTypes {
    release {
           ....
    }
    debug {
        ext.enableCrashlytics = false
    }
}

2
这样使用起来更加舒适,如果您在代码中对Crashlytics进行调用并且不在Application类之外,它将防止您的应用程序崩溃。 - speedynomads
1
它在Crashlytics 2.3.0中被弃用了 :( - Damian Walczak
1
ext.enableCrashlytics = false 对我来说也不起作用,即使在2.5版本之前,实际上它从来没有起作用过,甚至在Fabric之前。 - Bao-Long Nguyen-Trong
2
我在这里有一个疑虑。这会启用Answer和Beta吗? 看起来这样应该更正确:CrashlyticsCore core = new CrashlyticsCore.Builder().disabled(BuildConfig.DEBUG).build(); Fabric.with(this, new Answers(), new Beta(), new Crashlytics.Builder().core(core).build()); - gbero
1
ext.enableCrashlytics = false 如果正确使用,不会导致崩溃。如何解决崩溃问题,请参阅 Fabrics 文档:https://docs.fabric.io/android/crashlytics/build-tools.html。 - Frank
显示剩余13条评论

176

来自Crashlytics的Marc。以下是在进行调试构建时禁用Crashlytics的几种方法!

  1. 为调试和发布构建使用不同的android:versionString,然后在Crashlytics Web控制面板中禁用调试版本的崩溃报告。

  2. 将对Crashlytics.start()的调用包装在检查调试标志的if语句中。您可以使用自定义标志或类似于此处提出的方法:如何检查APK是否已签名或为“debug build”?


6
使用 BuildConfig.DEBUG 可以吗? - dannyroa
3
BuildConfig.DEBUG并非所有构建环境下都通用的标志。我认为在使用Eclipse和ADT进行构建时会始终设置它,但在其他地方可能不会。 - marcr
14
如果你正在使用Gradle构建项目,应该使用BuildConfig.DEBUG。它将始终被正确地生成。 - Austyn Mahoney
3
在最新版本的Crashlytics中(似乎已与Fabric合并),库会对BuildConfig.DEBUG进行内部检查吗? - akhy
2
@akhyar 它不会自动检查,我使用以下代码:if (!BuildConfig.DEBUG) {Fabric.with(this, new Crashlytics());} - Björn Kechel
显示剩余6条评论

50
所选答案不再正确。Google 更改了Crashlytics的集成方式。我的当前版本是2.9.1,我所做的唯一事情就是将implementation 'com.crashlytics.sdk.android:crashlytics:2.9.1'添加到我的Gradle文件中。不需要进一步的操作,这很好,但这意味着Crashlytics始终在运行。 解决方案1 只在发布版本中编译Crashlytics:
dependencies {
   ...
   releaseImplementation 'com.crashlytics.sdk.android:crashlytics:2.9.1' // update version
}

解决方案2

如果您想要额外配置Crashlytics,那么解决方案1将不起作用,因为在Debug Builds中找不到Crashlytics类。因此,请将Gradle实现更改回:

implementation 'com.crashlytics.sdk.android:crashlytics:2.9.1' // update version

然后前往您的清单并在application标记内添加以下meta-data标记:

<application
        android:name="...>

        <meta-data
            android:name="firebase_crashlytics_collection_enabled"
            android:value="false" />

...

</application>

将以下代码添加到启动活动(仅需一次,不需要每个活动都添加)

if (!BuildConfig.DEBUG) { // only enable bug tracking in release version
   Fabric.with(this, new Crashlytics());
}

这将仅在发布版本中启用Crashlytics。要小心,配置Crashlytics时还要检查BuildConfig.DEBUG,例如:

if (!BuildConfig.DEBUG) {
   Crashlytics.setUserIdentifier("HASH_ID");
}

2
这看起来很干净。不如在应用程序实例中而不是在主要活动中进行初始化? - jules
他们在网站上说:“通过从应用程序的一个活动初始化Crashlytics来启用对选定用户的收集”,但我想,如果您在应用程序中初始化Crashlytics,则不会有太大变化。 您试过了吗? 如果起作用,那么我可以将其添加到我的答案中。https://firebase.google.com/docs/crashlytics/customize-crash-reports - Paul Spiesberger
2
我无法让其他解决方案在运行时禁用Crashlytics。解决方案1完美地解决了问题,为什么我之前没有想到呢? - user409460
感谢您提供的解决方案。当我在清单文件中将 firebase_crashlytics_collection_enabled 设置为 false 时,控制台上就不会出现崩溃信息(我使用的是 v2.9.9 版本)。因此,我通过添加一个专门针对调试版本的清单文件来解决了这个问题,其中 firebase_crashlytics_collection_enabled 的值分别设置为 false 和 true。 - Vasily Kabunov

30

如果您使用Gradle,只需将以下内容添加到Flavor中:

ext.enableCrashlytics = false

1
这只是为了口感吗?调试和发布有什么区别?我尝试在调试模式下禁用,但仍然发送崩溃。 - xialin
我认为它只适用于特定版本。 在我看来,使用Austyn和Marcc指出的标志是最简单的。 - user1998494
我找到了解决方案。但不确定它是否与旧版Crashlytics兼容。这是针对Fabric SDK中的新Crashlytics。请查看下面的答案。 - xialin
2
该命令禁用发送Crashlytics映射文件和为每个构建生成ID,从而加快这些风格的gradle构建速度。(它不会在运行时禁用Crashlytics。)请参见Mike B在此处的答案:https://dev59.com/bIfca4cB1Zd3GeqPkZHJ#28357998 - Aphex
19
这导致了一次崩溃... "这款应用程序依赖于Crashlytics。" - Sakiboy
它也导致了我的应用崩溃,所以我按照上面的答案建议,在Application的onCreate方法中禁用了它,然后它就正常工作了。 - cristianorbs

28

请查看最新文档。 https://docs.fabric.io/android/crashlytics/build-tools.html#gradle-advanced-setup

除了在build.grade文件中添加ext.enableCrashlytics = false之外,您还需要执行以下操作:

Crashlytics crashlyticsKit = new Crashlytics.Builder()
    .core(new CrashlyticsCore.Builder().disabled(BuildConfig.DEBUG).build())
    .build();

// Initialize Fabric with the debug-disabled crashlytics.
Fabric.with(this, crashlyticsKit);

我尝试了这种方法,但应用程序仍然崩溃并显示“此应用程序依赖于Crashlytics。请注册以获取访问权限”。 - Kostadin Georgiev
我猜你在 build.gradle 中缺少 ext.enableCrashlytics = false - Abhishek Patidar
不,我已经在 build.gradle 文件中添加了调试构建类型,它在 buildTypes -> debug 中,同时我也通过 apply plugin: 'io.fabric' 应用了插件。 - Kostadin Georgiev
我甚至不确定为什么这个解决方案会得到24次赞同。出现错误:“此应用程序依赖于Crashlytics。请在https://fabric.io/sign_up注册以获取访问权限”。 - trod

24

我发现这个是最简单的解决方案:

    release {
        ...
        buildConfigField 'Boolean', 'enableCrashlytics', 'true'
    }
    debug {
        buildConfigField 'Boolean', 'enableCrashlytics', 'false'
    }

上述代码将在 BuildConfig 文件中创建一个名为 enableCrashlytics 的静态布尔字段,您可以使用它来决定是否启动 Fabric。
    if (BuildConfig.enableCrashlytics)
        Fabric.with(this, new Crashlytics());

注意: 使用这种方法,Fabrics 仅在发布版本中初始化(如上面的代码所示)。这意味着您需要将对静态方法的调用放置在一个 if 块中,该块检查 Fabrics 是否已被初始化,如下所示。

if (Fabric.isInitialized())
    Crashlytics.logException(e);

否则,在模拟器上进行测试时,应用程序将崩溃并显示“必须在使用singleton()之前初始化Fabric”的错误。

24

2019年答案

我花了2个小时尝试只在发布版本中启用Crashlytics,在调试版本中禁用,并检查Firebase控制台以查看异常是否已上传。

有两种可能的方法。

选项1

这是可行的,但如果您在调试构建上调用任何Crashlytics方法,则应用程序将崩溃

app/build.gradle

android {
    buildTypes {
        release {
            manifestPlaceholders = [crashlyticsEnabled: true]
        }
        debug {
            manifestPlaceholders = [crashlyticsEnabled: false]
        }

AndroidManifest.xml

<manifest
    <application
        <meta-data
            android:name="firebase_crashlytics_collection_enabled"
            android:value="${crashlyticsEnabled}" />

选项 2

一种替代方法,可以让您在调用 Crashlytics 方法之前无需检查 BuildConfig.DEBUG。使用此设置,您可以安全地调用类似于 Crashlytics.logException() 的方法 - 它们在调试版本中不做任何操作。我没有看到报告在调试版本中被上传。

app/build.gradle

android {
    buildTypes {
        release {
            ext.enableCrashlytics = true
        }
        debug {
            ext.enableCrashlytics = false
        }

AndroidManifest.xml

<manifest
    <application
        <meta-data
            android:name="firebase_crashlytics_collection_enabled"
            android:value="false" />

应用程序 onCreate()

val crashlytics = Crashlytics.Builder()
    .core(CrashlyticsCore.Builder().disabled(BuildConfig.DEBUG).build())
    .build()
Fabric.with(this, crashlytics)

2
我认为android:value="false"必须更改为android:value="${enableCrashlytics}"。不是吗? - JaydeepW
使用第二种选项的另一个优点是,您最初禁用分析收集,然后可以先询问用户是否允许跟踪其应用程序使用情况(考虑GDPR)。如果用户同意跟踪,则只需执行Fabric.with调用。 - Per Christian Henden
选项#2的唯一缺点是,即使在Firebase仪表板中不显示崩溃(因为它们被禁用了),它仍会创建调试版本。这会带来两个问题-首先,它使查找发布版本更加困难;其次-Firebase仪表板仅显示最后100个版本,这可能会阻止您在某些旧版本中看到崩溃。在Fabric仪表板中,您可以禁用特定版本,但在Firebase的仪表板中不可能 - Alex Lipov

15

MyApplication#onCreate()中使用此功能。

if (!BuildConfig.DEBUG) Crashlytics.start(this);

编辑 如果你升级到了Fabric,请使用这个答案


BuildConfig.DEBUG并不总是正确设置。在使用IntelliJ时,依赖它来启用/禁用Crashlytics给我带来了很多问题。 - Zeb Barnett
5
你使用哪些构建工具? Gradle将始终设置该值。 这是一年前的问题,但新的构建工具要好得多。 - Austyn Mahoney
我正在使用IntelliJ的Gradle插件版本为v0.9.+,Gradle本身的版本为v1.11。 - Zeb Barnett
我在我的任何应用程序中都没有发现任何问题。BuildConfig是由Gradle任务生成的,这是有保证运行的。我还使用buildConfigField来设置自定义字段,这些字段总是有效的。http://tools.android.com/recent/androidstudio045released 还建议您使用BuildConfig.DEBUG - Austyn Mahoney
作为一个理想主义者,我肯定希望能够使用它,因为它可以简化我所在的小公司不太自动化的构建过程。只是我们发布了一个依赖于该标志的构建版本,并且Crashlytics从未看到它上线。当我们手动切换回去后,Crashlytics立即看到了它。 - Zeb Barnett
鉴于您的经验与实际文档所说的相矛盾,我将继续使用该标志。我已经看到很多其他开源应用程序也在使用它。 - Austyn Mahoney

11

我喜欢的另一种简单解决方案,因为它不需要不同的清单文件:

步骤1-在build.gradle中定义清单占位符。

android {
    ...
    buildTypes {
        release {
            manifestPlaceholders = [crashlytics:"true"]
        }
        debug {
            manifestPlaceholders = [crashlytics:"false"]
        }
    }
    ...
}

第二步-在AndroidManifest.xml中使用它们

<meta-data
        android:name="firebase_crashlytics_collection_enabled"
        android:value="${crashlytics}" />

10

2022年使用FirebaseCrashlytics的答案。

有两种情况:

  1. 如果您想为所有应用程序运行禁用Crashlytics数据收集(例如在调试模式下禁用Crashlytics),则需要在清单文件中将标记firebase_crashlytics_collection_enabled设置为false来禁用它。

build.gradle(:app)

// Next two flags to enable/disable Crashlytics
def enableCrashlyticsInDebugBuild = false
def enableCrashlyticsInReleaseBuild = true


android {
  buildTypes {

        release {
                manifestPlaceholders = [crashlyticsEnabled:"${enableCrashlyticsInReleaseBuild}"]
        }

        debug {
                manifestPlaceholders = [crashlyticsEnabled:"${enableCrashlyticsInDebugBuild}"]
        }
  }
}

然后在清单文件中,在application标签下添加以下内容。

<meta-data
            android:name="firebase_crashlytics_collection_enabled"
            android:value="${crashlyticsEnabled}" />
  1. 如果你想要让某些用户在选择退出数据收集时禁用Crashlytics。

为处理该情况,你应该使用setCrashlyticsCollectionEnabled方法。

Kotlin API(Java API相似):

FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(false)

当设置为false时,新值直到下一次应用程序运行才会生效。

参考资料:

  1. https://firebase.google.com/docs/crashlytics/customize-crash-reports?platform=android#enable-reporting

  2. https://firebase.google.com/docs/reference/kotlin/com/google/firebase/crashlytics/FirebaseCrashlytics#setcrashlyticscollectionenabled


这对我有用。之前,我一直在使用 extra["enableCrashlytics"] = false,但它没有起作用。 - Mark
请将manifestPlaceholders ["crashlyticsEnabled"]更正为false/true。在这种具体情况下,使用变量并没有增加解决方案的价值。 - David
@David 添加标识符可以让开发人员更加控制启用/禁用而无需深入了解内部细节。变量具有描述性,直接进行更改即可。不需要检查和阅读代码以了解更新位置。 - Mahmoud

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接