Crashlytics Android SDK - пользовательский UncaughtExceptionHandler
Можно ли включить в одно приложение пользовательский UncaughtExceptionHandler вместе с crashlytics? Если да - как?
Ответы
Ответ 1
Поскольку последние версии Crashlytics выполняют инициализацию асинхронно, лучше использовать обратный вызов инициализации Fabric:
private static Thread.UncaughtExceptionHandler mDefaultUEH;
private static Thread.UncaughtExceptionHandler mCaughtExceptionHandler =
new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable ex) {
// Custom logic goes here
// This will make Crashlytics do its job
mDefaultUEH.uncaughtException(thread, ex);
}
};
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) {
mDefaultUEH = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(mCaughtExceptionHandler);
}
@Override
public void failure(Exception e) {
}
})
.build());
Ответ 2
ОБНОВИТЬ
Пожалуйста, смотрите ответ @kmityak, так как инициализация Crashlytics/Fabric теперь асинхронна, и мое решение ниже недействительно.
ОРИГИНАЛЬНЫЙ ОТВЕТ
Вы можете установить свой собственный UncaughtExceptionHandler при условии, что он передаст исключение по умолчанию UncaughtExceptionHandler для последующей обработки через Crashlytics.
Ниже код реализован внутри подкласса приложения:
private static Thread.UncaughtExceptionHandler mDefaultUEH;
private static Thread.UncaughtExceptionHandler mCaughtExceptionHandler = new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable ex) {
// Custom logic goes here
// This will make Crashlytics do its job
mDefaultUEH.uncaughtException(thread, ex);
}
};
@Override
public void onCreate() {
super.onCreate();
// Order is important!
// First, start Crashlytics
Crashlytics.start(this);
// Second, set custom UncaughtExceptionHandler
mDefaultUEH = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(mCaughtExceptionHandler);
}
Второй вариант - зарегистрировать Crashlytics после установки своего пользовательского UncaughtExceptionHandler - тогда Crashlytics будет сообщать обо всех неперехваченных исключениях как фатальные, а после этого будет передан вашему пользовательскому обработчику.
Ответ 3
Да, это возможно.
В вашем классе Application:
@Override
public void onCreate() {
super.onCreate();
Crashlytics.start(this);
initUncaughtExceptionHandler();
}
private void initUncaughtExceptionHandler() {
final ScheduledThreadPoolExecutor c = new ScheduledThreadPoolExecutor(1);
c.schedule(new Runnable() {
@Override
public void run() {
final UncaughtExceptionHandler defaultHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread paramThread, Throwable paramThrowable) {
// do my amazing stuff here
System.err.println("Error!");
//then pass the job to the previous handler
defaultHandler.uncaughtException(paramThread, paramThrowable);
}
});
}
}, 5, TimeUnit.SECONDS);
}
Причина, по которой я планирую это через 5 секунд, заключается в том, что Crashlytics нужно некоторое время, чтобы настроить его. Я использую этот код, и он работает отлично. Конечно, если ваше приложение аварийно завершает работу, извините, но не пользовательский обработчик;)
Ответ 4
Нет, если эти решения будут работать для меня. Я сделал это следующим образом:
// Setup handler for uncaught exceptions.
Thread.setDefaultUncaughtExceptionHandler (new Thread.UncaughtExceptionHandler()
{
@Override
public void uncaughtException (Thread thread, Throwable e)
{
//Send Report to Crashlytics. Crashlytics will send it as soon as it starts to work
Crashlytics.logException(e);
//Your custom codes to Restart the app or handle this crash
HandleCrashes(thread, e);
}
});
И вот мой пользовательский метод для перезапуска APP:
private void HandleCrashes(Thread t, Throwable e) {
Intent i = new Intent(mContext, frmLogin.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.putExtra("JustLogin", true);
startActivity(i);
System.exit(1);
}
Ответ 5
Я нашел решение для Fabric 2.10.1:
Thread.setDefaultUncaughtExceptionHandler(yourExceptionHandler)
Fabric.with(this, Crashlytics())