我已经成功实现了Firebase Crash Reporting,但是我需要在应用运行时禁用该服务,并撤消“调试” Build Variant,以避免开发过程中控制台发生非真实的崩溃。
官方文档对此没有任何说明。
我已经成功实现了Firebase Crash Reporting,但是我需要在应用运行时禁用该服务,并撤消“调试” Build Variant,以避免开发过程中控制台发生非真实的崩溃。
官方文档对此没有任何说明。
releaseCompile 'com.google.firebase:firebase-crash:9.8.0'
这行不行吗?应该只为您的发行版本添加依赖项,因此在开发库时不会将其添加到项目中,对吗?
Answers:
更新:使用Google Play服务/ Firebase 11+,您现在可以在运行时禁用崩溃报告。FirebaseCrash.setCrashCollectionEnabled()
(感谢@Tyler Carberry)
旧答案:
只要社区能够推测,就没有官方的支持。我建议执行此操作的最佳方法是,在仪表板中设置多个Firebase应用程序,每种构建类型一个,并根据构建版本设置多个指向每个不同应用程序的google_services.json文件。
使用Google Play服务11.0,您现在可以在运行时禁用崩溃报告。
FirebaseCrash.setCrashCollectionEnabled(!BuildConfig.DEBUG);
最近引入了以官方方式禁用Firebase崩溃报告的可能性。您需要将Firebase Android SDK升级到至少11.0.0版本
为此,您需要编辑AndroidManifest.xml
并添加:
<meta-data
android:name="firebase_crashlytics_collection_enabled"
android:value="false" />
里面的<application>
块。
您可以使用FirebaseCrash.isCrashCollectionEnabled()在运行时检查是否启用了Firebase崩溃报告。
下面是一个在调试版本中禁用Firebase崩溃报告的完整示例。
build.gradle:
...
buildTypes {
release {
...
resValue("bool", "FIREBASE_CRASH_ENABLED", "true")
}
debug {
...
resValue("bool", "FIREBASE_CRASH_ENABLED", "false")
}
}
...
dependencies {
...
compile "com.google.firebase:firebase-core:11.0.0"
compile "com.google.firebase:firebase-crash:11.0.0"
...
}
AndroidManifest.xml:
<application>
<meta-data
android:name="firebase_crash_collection_enabled"
android:value="@bool/FIREBASE_CRASH_ENABLED"/>
...
firebase_crash_collection_enabled
适用于Firebase 9.2.1版吗?
在我的应用程序类中,onCreate()
if (BuildConfig.DEBUG) {
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread paramThread, Throwable paramThrowable) {
Log.wtf("Alert", paramThrowable.getMessage(), paramThrowable);
System.exit(2); //Prevents the service/app from freezing
}
});
}
它之所以有效,是因为它需要oldHandler,其中包括Firebase 1
final UncaughtExceptionHandler oldHandler = Thread.getDefaultUncaughtExceptionHandler();
走出处理路径
您可以将firebase崩溃依赖项更改为仅发行依赖项。
为此,您将其定义为releaseCompile依赖项
releaseCompile 'com.google.firebase:firebase-crash:9.4.0'
现在,它将仅包含在发行版本中。如果您想要崩溃报告的其他自定义构建类型,则可以将其添加到其中。
customBuildTypeCompile 'com.google.firebase:firebase-crash:9.4.0'
受到这个相关答案的启发和此处其他,我想出了这个方便的解决方案。
使用Timber进行记录,我为调试和发布版本创建了Tree子类的不同实现。在调试中,它遵从写入到logcat的DebugTree。在发行版中,它将转发异常和高优先级日志到Firebase,其余部分则丢弃。
build.gradle
dependencies {
...
compile 'com.jakewharton.timber:timber:4.3.0'
releaseCompile 'com.google.firebase:firebase-crash:9.0.2'
}
src / debug / java / [package] /ForestFire.java
import timber.log.Timber;
public class ForestFire extends Timber.DebugTree {}
src / release / java / [package] /ForestFire.java
import android.util.Log;
import com.google.firebase.crash.FirebaseCrash;
import timber.log.Timber;
public class ForestFire extends Timber.Tree {
@Override
protected void log(int priority, String tag, String message, Throwable t) {
if (Log.WARN <= priority) {
FirebaseCrash.log(message);
if (t != null) {
FirebaseCrash.report(t);
}
}
}
}
应用启动
Timber.plant(new ForestFire());
首先在gradle文件中初始化变量,然后检查它是处于调试模式还是处于释放模式。提交崩溃报告的最佳方法是在Application类中。
Build.gradle
buildTypes {
release {
buildConfigField "Boolean", "REPORT_CRASH", '"true"'
debuggable false
}
debug {
buildConfigField "Boolean", "REPORT_CRASH", '"false"'
debuggable true
}
}
现在首先检查模式,如果崩溃则提交崩溃报告。
应用程序
/** Report FirebaseCrash Exception if application crashed*/
Thread.setDefaultUncaughtExceptionHandler (new Thread.UncaughtExceptionHandler()
{
@Override
public void uncaughtException (Thread thread, Throwable e)
{
/** Check whether it is development or release mode*/
if(BuildConfig.REPORT_CRASH)
{
FirebaseCrash.report( e);
}
}
});
尽管您可以停用Firebase分析,但当前您无法禁用Firebase崩溃报告。
因此,一种方法是在同一个Firebase项目中创建另一个具有不同ID的应用。之后,您只需要更改appID即可启用或禁用Firebase崩溃报告。为了方便起见,我在下面创建了两个应用程序:
AppID:com.android-发布版本类型
AppID:com.android.debug-用于调试构建类型
请点击以下链接了解更多详情:
https://firebase.googleblog.com/2016/08/organizing-your-firebase-enabled-android-app-builds.html
编辑: 您不需要一次又一次地更改android项目中的appID。有一种更好的方法可以将不同的appID用于调试版本类型-
android {
defaultConfig {
applicationId "com.android"
...
}
buildTypes {
debug {
applicationIdSuffix ".debug"
}
}
}
查看链接以获取更多详细信息:
https://developer.android.com/studio/build/application-id.html
编辑2:
基本上,在上述解决方案中,您将在Firebase项目中制作两个不同的应用程序,并且通过这种方式,您可以区分开发和生产错误。
不建议使用FYI Firebase崩溃报告。您应该使用Fabrics Crashlytics(由Google拥有)。它具有一些非常酷的功能。
对于FirebaseAnalytics
类。
禁用收集:setAnalyticsCollectionEnabled(false);
启用收集:setAnalyticsCollectionEnabled(true);
或AndroidManifest.xml
在应用程序标签中写入:<meta-data android:name="firebase_analytics_collection_enabled" android:value="false" />
可能的用途:
if (BuildConfig.DEBUG){ //disable for debug
mFirebaseAnalytics.setAnalyticsCollectionEnabled(false);
}
首先,您将必须创建debug
和release
构建变体,然后使用布尔值设置变量。然后,您需要从扩展的Java文件中获取该值,application
即从启用位置开始Fabric
崩溃报告的位置开始。
下面给出一个代码示例。
在您的应用程序的build.gradle
文件,添加以下行来创建2个构建变量debug
和release
,然后添加一个变量与布尔值。
defaultConfig {
buildConfigField 'boolean', 'ENABLE_ANALYTICS', 'true'
}
buildTypes {
debug {
applicationIdSuffix ".debug"
versionNameSuffix 'DEBUG'
buildConfigField 'boolean', 'ENABLE_ANALYTICS', 'false'
}
release {
minifyEnabled false
}
}
然后,当您尝试添加Fabric
崩溃报告时,请检查以下值:ENABLE_ANALYTICS
公共类测试扩展了应用{
private GoogleAnalytics googleAnalytics;
private static Tracker tracker;
@Override
public void onCreate() {
super.onCreate();
if (BuildConfig.ENABLE_ANALYTICS)
Fabric.with(this, new Crashlytics());
}
}
您可以ENABLE_ANALYTICS
通过ctrl
+单击值来查看的值。希望这可以帮助。
当用户以Debug模式或Release模式运行应用程序时,最简单的解决方案是:
AndroidManifest.xml:
<meta-data
android:name="firebase_crash_collection_enabled"
android:value="${analytics_deactivated}"/>
build.gradle(模块:应用)
buildTypes {
debug {
manifestPlaceholders = [analytics_deactivated: "false"]
}
release {
manifestPlaceholders = [analytics_deactivated: "true"]
}
}
因此,当应用程序处于发布模式时,crashlatics将被打开,而应用程序将在调试模式下运行,它将被关闭。
我versionCode
用作本地/生产版本的过滤器。
gradle.properties
VERSION_CODE=1
app / build.gradle
android {
defaultConfig {
versionCode VERSION_CODE as int
}
}
发布新版本的应用程序时,只需从命令行设置新值:
./gradlew build -PVERSION_CODE=new_value
否则,从Android Studio进行构建时,您将始终获得相同的信息versionCode
,因此您可以轻松地在Firebase控制台中区分崩溃报告。
如前所述-没有官方的方法可以做到这一点。但是如@ mark-d所述,对我来说最糟糕的解决方法是重置DefaultUncaughtExceptionHandler
(https://stackoverflow.com/a/39322734/4245651)。
但是,如果您只是System.exit(2)
按照建议的方式进行呼叫-该应用程序将在异常情况下立即关闭,而不会出现任何对话框消息并且很难获取调试日志。如果这对您很重要,则有一种方法可以还原默认处理程序:
if (BuildConfig.DEBUG) {
final Thread.UncaughtExceptionHandler currentHandler = Thread.getDefaultUncaughtExceptionHandler();
if (currentHandler.getClass().getPackage().getName()
.startsWith("com.google.firebase")) {
final Thread.UncaughtExceptionHandler defaultHandler =
getPrivateFieldByType(currentHandler, Thread.UncaughtExceptionHandler.class);
Thread.setDefaultUncaughtExceptionHandler(defaultHandler);
}
}
哪里
public static <T> T getPrivateFieldByType(Object obj, Class<T> fieldType) {
if (obj != null && fieldType != null) {
for (Field field : obj.getClass().getDeclaredFields()) {
if (field.getType().isAssignableFrom(fieldType)) {
boolean accessible = field.isAccessible();
if (!accessible) field.setAccessible(true);
T value = null;
try {
//noinspection unchecked
value = (T) field.get(obj);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
if (!accessible) field.setAccessible(false);
return value;
}
}
}
return null;
}
if (!development) { FirebaseCrash.report(e);}