Идеальный способ установить глобальный обработчик неперехваченных исключений в Android
Я хочу установить глобальный обработчик необработанных исключений для всех потоков в моем приложении для Android. Итак, в моем Application подкласс я установил реализацию Thread.UncaughtExceptionHandler как обработчик по умолчанию для неперехваченных исключений.
Thread.setDefaultUncaughtExceptionHandler(
new DefaultExceptionHandler(this));
в моей реализации, я пытаюсь отобразить AlertDialog отображение соответствующего сообщения об исключении.
однако, это, кажется, не работает. Всякий раз, когда возникает исключение для любого потока, который не обрабатывается, я получаю запас, OS-default диалог ("извините!- Приложение-остановилось-неожиданно диалог").
каков правильный и идеальный способ установить обработчик по умолчанию для неперехваченных исключений?
5 ответов:
Это должно быть все, что вам нужно сделать. (Убедитесь, что вы заставите процесс остановиться после этого-все может быть в неопределенном состоянии.)
первое, что нужно проверить, является ли Android обработчик по-прежнему вызывается. Возможно, что ваша версия вызывается, но не работает фатально, и system_server показывает общий диалог, когда он видит сбой процесса.
добавить некоторые сообщения журнала в верхней части обработчика, чтобы увидеть, если есть проблема. Распечатать результат из getDefaultUncaughtExceptionHandler, а затем бросить неперехваченное исключение, чтобы вызвать сбой. Следите за выводом logcat, чтобы увидеть, что происходит.
я разместил простой решение для пользовательской обработки Android падает давно. Это немного хаки, однако он работает на всех версиях Android (в том числе леденец).
сначала немного теории. Основные проблемы при использовании Uncaught обработчик исключений в Android приходят с исключениями, брошенными в основной (ака UI) поток. И вот почему. Когда приложение запускает системные вызовы ActivityThread.главное метод, который подготавливает и запускает Главная петлителя приложения:
public static void main(String[] args) { … … Looper.prepareMainLooper(); … Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }Main looper отвечает за обработку сообщений, размещенных в потоке пользовательского интерфейса (включая все сообщения, связанные с визуализацией и взаимодействием пользовательского интерфейса). Если исключение создается в потоке пользовательского интерфейса, оно будет поймано вашим обработчиком исключений, но поскольку вы вышли из
loop()метод вы не сможете показать какой-либо диалог или активность для пользователя, так как не осталось никого, чтобы обрабатывать сообщения пользовательского интерфейса для вас.предлагаемое решение совсем простой. Мы бежим
Looper.loopметод наш собственный и окружить его с try-catch блок. Когда исключение поймано, мы обрабатываем его так, как хотим (например, запускаем нашу пользовательскую активность отчета) и вызываемLooper.loopопять способ.следующий метод демонстрирует этот метод (он должен быть вызван из
Application.onCreateслушатель):private void startCatcher() { UncaughtExceptionHandler systemUncaughtHandler = Thread.getDefaultUncaughtExceptionHandler(); // the following handler is used to catch exceptions thrown in background threads Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler(new Handler())); while (true) { try { Looper.loop(); Thread.setDefaultUncaughtExceptionHandler(systemUncaughtHandler); throw new RuntimeException("Main thread loop unexpectedly exited"); } catch (Throwable e) { showCrashDisplayActivity(e); } } }как вы можете видеть, обработчик неперехваченных исключений используется только для исключения фоновых потоков. Следующий обработчик ловит эти исключения и распространяет их в поток пользовательского интерфейса:
static class UncaughtHandler implements UncaughtExceptionHandler { private final Handler mHandler; UncaughtHandler(Handler handler) { mHandler = handler; } public void uncaughtException(Thread thread, final Throwable e) { mHandler.post(new Runnable() { public void run() { throw new BackgroundException(e); } }); } }пример проекта, который использует эту технику, доступен на моем репозитории GitHub:https://github.com/idolon-github/android-crash-catcher
FWIW я знаю, что это немного не по теме, но мы использовали свободный план Crittercism С успехом. Они также предлагают некоторые премиум-функции, такие как обработка исключения, чтобы приложение не рухнуло.
в бесплатной версии пользователь все еще видит сбой, но по крайней мере я получаю электронную почту и трассировку стека.
мы также используем версию iOS (но я слышал от моих коллег, что это не совсем хорошо).
вот похожие вопросы:
Я думаю, чтобы отключить, что в вашем uncaughtException() метод не вызывает previousHandler.uncaughtException () где previousHandler задается
previousHandler = Thread.getDefaultUncaughtExceptionHandler();
Он не работает, пока вы не позвоните
android.os.Process.killProcess(android.os.Process.myPid());в самом конце вашего UncaughtExceptionHandler.
Comments