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())