使用自定义 UncaughtExceptionHandler 升级 Firebase Crashlytics
Upgrade Firebase Crashlytics with custom UncaughtExceptionHandler
在 Update your apps to use latest Firebase Crashlytics SDKs before November 15, 2020
上工作时,在我激活自定义 UncaughtExceptionHandler
后,它不会再向 Crashlytics 发送崩溃。
下面的代码我将它设置在 Application
的 onCreate()
内。
FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
crashlytics.setCrashlyticsCollectionEnabled(!BuildConfig.DEBUG); // only release able to send.
crashlytics.sendUnsentReports(); // send reports
Thread.setDefaultUncaughtExceptionHandler((t, e) -> {
FirebaseCrashlytics.getInstance().recordException(e); // record exception.
// below things are restart app when crash appeared.
PackageManager packageManager = getPackageManager();
Intent intent = packageManager.getLaunchIntentForPackage(getPackageName());
if (intent != null) {
ComponentName componentName = intent.getComponent();
Intent mainIntent = Intent.makeRestartActivityTask(componentName);
startActivity(mainIntent);
Runtime.getRuntime().exit(0);
}
});
当我删除自定义 UncaughtExceptionHandler
时,它能够向 Crashlytics 报告。
以下代码在使用 Fabric 库时运行良好。 ()
CrashlyticsCore core = new CrashlyticsCore.Builder()
.disabled(BuildConfig.DEBUG)
.build();
Fabric.with(new Fabric.Builder(this).kits(new Crashlytics.Builder()
.core(core).build()).initializationCallback(new InitializationCallback<Fabric>() {
@Override
public void success(Fabric fabric) {
Thread.setDefaultUncaughtExceptionHandler((t, e) -> {
LogWrapper.logException(e);
PackageManager packageManager = getPackageManager();
Intent intent = packageManager.getLaunchIntentForPackage(getPackageName());
if (intent != null) {
ComponentName componentName = intent.getComponent();
Intent mainIntent = Intent.makeRestartActivityTask(componentName);
startActivity(mainIntent);
Runtime.getRuntime().exit(0);
}
});
}
@Override
public void failure(Exception e) {
e.printStackTrace();
}
}).build());
有什么解决办法吗?任何帮助将不胜感激。非常感谢。
您需要调用 getUncaughtExceptionHandler 并挂起,然后设置您自己的 uncaughtexceptionhandler 并在退出前调用我们的。
解决方案是 posted here。我会将修改后的代码粘贴到此处以供寻找它的任何人使用:
下面的代码写在Java。 Kotlin请访问原文post.
public class NewCrashHandlerContentProvider extends ContentProvider {
public static final String TAG = "NewCrashHandler";
static long PRE_DELAY_MILLIS = 3000L;
static long POST_DELAY_MILLIS = 3000L;
public static void initializeAfterFirebaseContentProvider() {
Thread.setDefaultUncaughtExceptionHandler(new PreFirebaseCrashHandler(Thread.getDefaultUncaughtExceptionHandler()));
}
@Override
public boolean onCreate() {
try {
Log.i(TAG, "+onCreate()");
Thread.setDefaultUncaughtExceptionHandler(new PostFirebaseCrashHandler(Thread.getDefaultUncaughtExceptionHandler()));
return true;
}finally {
Log.i(TAG, "-onCreate()");
}
}
@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
return null;
}
@Nullable
@Override
public String getType(@NonNull Uri uri) {
return null;
}
@Nullable
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
return null;
}
@Override
public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
return 0;
}
@Override
public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
return 0;
}
static class PreFirebaseCrashHandler implements Thread.UncaughtExceptionHandler {
Thread.UncaughtExceptionHandler previousUncaughtExceptionHandler;
public static final String TAG = "PreFirebaseCrashHandler";
public PreFirebaseCrashHandler(Thread.UncaughtExceptionHandler previousUncaughtExceptionHandler) {
this.previousUncaughtExceptionHandler = previousUncaughtExceptionHandler;
}
@Override
public void uncaughtException(@NonNull Thread t, @NonNull Throwable e) {
LogWrapper.logException(e);
try {
// my own logic
Thread.sleep(PRE_DELAY_MILLIS);
}catch (Throwable throwable) {
LogWrapper.e(TAG, throwable.getLocalizedMessage());
} finally {
previousUncaughtExceptionHandler.uncaughtException(t,e);
}
}
}
static class PostFirebaseCrashHandler implements Thread.UncaughtExceptionHandler {
Thread.UncaughtExceptionHandler previousUncaughtExceptionHandler;
public static final String TAG = "PostFirebaseCrashHandler";
public PostFirebaseCrashHandler(Thread.UncaughtExceptionHandler previousUncaughtExceptionHandler) {
this.previousUncaughtExceptionHandler = previousUncaughtExceptionHandler;
}
@Override
public void uncaughtException(@NonNull Thread t, @NonNull Throwable e) {
LogWrapper.e(TAG, "+uncaughtException($thread, $throwable)");
try {
Thread.sleep(POST_DELAY_MILLIS);
}catch (Throwable throwable) {
LogWrapper.e(TAG, throwable.getLocalizedMessage());
}finally {
previousUncaughtExceptionHandler.uncaughtException(t,e);
}
LogWrapper.e(TAG, e.getLocalizedMessage());
}
}
}
在Application文件中,在onCreate()
方法中写入:
NewCrashHandlerContentProvider.initializeAfterFirebaseContentProvider();
也别忘了更新manifests
<provider
android:authorities="${applicationId}"
android:name=".utils.NewCrashHandlerContentProvider"
android:exported="false"
android:initOrder="101"
android:grantUriPermissions="false"/>
在 Update your apps to use latest Firebase Crashlytics SDKs before November 15, 2020
上工作时,在我激活自定义 UncaughtExceptionHandler
后,它不会再向 Crashlytics 发送崩溃。
下面的代码我将它设置在 Application
的 onCreate()
内。
FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
crashlytics.setCrashlyticsCollectionEnabled(!BuildConfig.DEBUG); // only release able to send.
crashlytics.sendUnsentReports(); // send reports
Thread.setDefaultUncaughtExceptionHandler((t, e) -> {
FirebaseCrashlytics.getInstance().recordException(e); // record exception.
// below things are restart app when crash appeared.
PackageManager packageManager = getPackageManager();
Intent intent = packageManager.getLaunchIntentForPackage(getPackageName());
if (intent != null) {
ComponentName componentName = intent.getComponent();
Intent mainIntent = Intent.makeRestartActivityTask(componentName);
startActivity(mainIntent);
Runtime.getRuntime().exit(0);
}
});
当我删除自定义 UncaughtExceptionHandler
时,它能够向 Crashlytics 报告。
以下代码在使用 Fabric 库时运行良好。 ()
CrashlyticsCore core = new CrashlyticsCore.Builder()
.disabled(BuildConfig.DEBUG)
.build();
Fabric.with(new Fabric.Builder(this).kits(new Crashlytics.Builder()
.core(core).build()).initializationCallback(new InitializationCallback<Fabric>() {
@Override
public void success(Fabric fabric) {
Thread.setDefaultUncaughtExceptionHandler((t, e) -> {
LogWrapper.logException(e);
PackageManager packageManager = getPackageManager();
Intent intent = packageManager.getLaunchIntentForPackage(getPackageName());
if (intent != null) {
ComponentName componentName = intent.getComponent();
Intent mainIntent = Intent.makeRestartActivityTask(componentName);
startActivity(mainIntent);
Runtime.getRuntime().exit(0);
}
});
}
@Override
public void failure(Exception e) {
e.printStackTrace();
}
}).build());
有什么解决办法吗?任何帮助将不胜感激。非常感谢。
您需要调用 getUncaughtExceptionHandler 并挂起,然后设置您自己的 uncaughtexceptionhandler 并在退出前调用我们的。
解决方案是 posted here。我会将修改后的代码粘贴到此处以供寻找它的任何人使用:
下面的代码写在Java。 Kotlin请访问原文post.
public class NewCrashHandlerContentProvider extends ContentProvider {
public static final String TAG = "NewCrashHandler";
static long PRE_DELAY_MILLIS = 3000L;
static long POST_DELAY_MILLIS = 3000L;
public static void initializeAfterFirebaseContentProvider() {
Thread.setDefaultUncaughtExceptionHandler(new PreFirebaseCrashHandler(Thread.getDefaultUncaughtExceptionHandler()));
}
@Override
public boolean onCreate() {
try {
Log.i(TAG, "+onCreate()");
Thread.setDefaultUncaughtExceptionHandler(new PostFirebaseCrashHandler(Thread.getDefaultUncaughtExceptionHandler()));
return true;
}finally {
Log.i(TAG, "-onCreate()");
}
}
@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
return null;
}
@Nullable
@Override
public String getType(@NonNull Uri uri) {
return null;
}
@Nullable
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
return null;
}
@Override
public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
return 0;
}
@Override
public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
return 0;
}
static class PreFirebaseCrashHandler implements Thread.UncaughtExceptionHandler {
Thread.UncaughtExceptionHandler previousUncaughtExceptionHandler;
public static final String TAG = "PreFirebaseCrashHandler";
public PreFirebaseCrashHandler(Thread.UncaughtExceptionHandler previousUncaughtExceptionHandler) {
this.previousUncaughtExceptionHandler = previousUncaughtExceptionHandler;
}
@Override
public void uncaughtException(@NonNull Thread t, @NonNull Throwable e) {
LogWrapper.logException(e);
try {
// my own logic
Thread.sleep(PRE_DELAY_MILLIS);
}catch (Throwable throwable) {
LogWrapper.e(TAG, throwable.getLocalizedMessage());
} finally {
previousUncaughtExceptionHandler.uncaughtException(t,e);
}
}
}
static class PostFirebaseCrashHandler implements Thread.UncaughtExceptionHandler {
Thread.UncaughtExceptionHandler previousUncaughtExceptionHandler;
public static final String TAG = "PostFirebaseCrashHandler";
public PostFirebaseCrashHandler(Thread.UncaughtExceptionHandler previousUncaughtExceptionHandler) {
this.previousUncaughtExceptionHandler = previousUncaughtExceptionHandler;
}
@Override
public void uncaughtException(@NonNull Thread t, @NonNull Throwable e) {
LogWrapper.e(TAG, "+uncaughtException($thread, $throwable)");
try {
Thread.sleep(POST_DELAY_MILLIS);
}catch (Throwable throwable) {
LogWrapper.e(TAG, throwable.getLocalizedMessage());
}finally {
previousUncaughtExceptionHandler.uncaughtException(t,e);
}
LogWrapper.e(TAG, e.getLocalizedMessage());
}
}
}
在Application文件中,在onCreate()
方法中写入:
NewCrashHandlerContentProvider.initializeAfterFirebaseContentProvider();
也别忘了更新manifests
<provider
android:authorities="${applicationId}"
android:name=".utils.NewCrashHandlerContentProvider"
android:exported="false"
android:initOrder="101"
android:grantUriPermissions="false"/>