2010-05-04 1 views
81

Я хочу установить глобальный обработчик исключенных исключений для всех потоков в приложении для Android. Итак, в моем подклассе Application я установил реализацию Thread.UncaughtExceptionHandler как обработчик по умолчанию для неперехваченных исключений.Идеальный способ установки глобального неперехваченного исключения Handler в Android

Thread.setDefaultUncaughtExceptionHandler(
       new DefaultExceptionHandler(this)); 

В моей реализации, я пытаюсь отобразить AlertDialog отображения соответствующего сообщения об исключении.

Однако это не работает. Всякий раз, когда исключается какое-либо исключение для любого потока, который не обрабатывается, я получаю запас, диалог по умолчанию ОС («Извините! -Application-has-stop-неожиданный диалог»).

Каков правильный и идеальный способ установки обработчика по умолчанию для неперехваченных исключений?

+1

Можете ли вы поделиться код для того же .. –

+2

Если вы хотите зарегистрировать свои исключения, посмотрите http://acra.ch/. ACRA позволяет отправлять отчеты об ошибках в Google-Doc или вам через E-Mail. –

+1

@Alexander Или вы можете просто использовать Google Analytics для Android и регистрировать все исключения, которые вы хотите ... –

ответ

23

Это должно быть все, что вам нужно сделать. (Убедитесь, что вы заставляете процесс останавливаться после этого - все может быть в неопределенном состоянии.)

Первое, что нужно проверить, - это вызов обработчика Android. Возможно, ваша версия вызывается, но неудачно, и система system_server показывает общий диалог, когда видит сбои процесса.

Добавить несколько сообщений журналов в верхней части вашего обработчика, чтобы узнать, не попадает ли он туда. Распечатайте результат из getDefaultUncaughtExceptionHandler, а затем отбросьте неперехваченное исключение, чтобы вызвать сбой. Следите за выходом logcat, чтобы узнать, что происходит.

+10

«бросать неперехваченное исключение, чтобы вызвать сбой после обработки ошибки» по-прежнему важно. Я просто испытал это. Мое приложение закрылось после того, как я обработал исключение и не выбрал исключение. – OneWorld

+0

@OneWorld Jepp здесь же - по крайней мере, для блокирующей части - похоже, нет возможности «сохранить» приложение от сбоя в конце концов. – AgentKnopf

+0

@ Zainodis Я опубликовал слегка не по теме ответ на этот вопрос, дающий ссылку на Crittercism - я думаю, у них есть функция, которая позволяет вам «сохранить» приложение от сбоя в конце концов. Не уверен - я использую только бесплатную версию atm. –

3

Я думаю отключить, что в вашем uncaughtException() метод не называют previousHandler.uncaughtException(), где previousHandler устанавливается

previousHandler = Thread.getDefaultUncaughtExceptionHandler(); 
3

FWIW Я знаю, что это немного не по теме, но мы успешно использовали Crittercism's free plan. Они также предлагают некоторые премиальные функции, такие как обработка исключения, поэтому приложение не сбой.

В бесплатной версии пользователь все еще видит сбой, но по крайней мере я получаю электронную почту и трассировку стека.

Мы также используем версию iOS (но я слышал от своих коллег, что это не так хорошо).


Вот подобные вопросы:

1

Это не работает, пока вы не вызовете

android.os.Process.killProcess(android.os.Process.myPid()); 

на очень ан d вашего UncaughtExceptionHandler.

8

Я отправил простой solution для пользовательской обработки Android-сбоев давно. Это немного взломанный, но он работает на всех версиях Android (включая Lollipop).

Сначала немного теории. Основные проблемы, связанные с использованием обработчика исключенных обработчиков на Android, включают исключения, которые были выбраны в основном (aka UI) потоке. И вот почему.Когда приложение начнет система вызывает ActivityThread.main метод, который готовит и запускает Main looper вашего приложения:

public static void main(String[] args) { 
    … 
    … 
    Looper.prepareMainLooper(); 
    … 
    Looper.loop(); 
    throw new RuntimeException("Main thread loop unexpectedly exited"); 
} 

Главной петлителя несет ответственность за обработку сообщений, размещенные в потоке пользовательского интерфейса (включая все сообщения, связанные с оказанием UI и взаимодействием). Если исключение выбрано в потоке пользовательского интерфейса, оно будет улавливаться вашим обработчиком исключений, но поскольку вы не используете метод 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

+0

Как можно догадаться, таким образом можно не только показать пользовательский диалог ошибок, но также разрешить пользователю игнорировать исключение и продолжить работу с приложением (и, хотя это выглядит плохой идеей для опубликованных приложений, это может быть довольно удобным во время сеанса отладки или тестирования). – Idolon

+0

Привет, в то время как это работает в поиске нерешенных исключений, но по какой-то причине этот код всегда бросает исключения. Первоначально я, хотя это было из-за строки RuntimeException, которая у вас есть в методе startCatcher, но я все еще получаю исключение после ее удаления. Я не уверен, что это обязательная вещь. В любом случае исключением, которое я получаю, является 'java.lang.RuntimeException: выполнение паузы активности, которая не возобновляется'. Я считаю, что когда я пытаюсь запустить свой собственный петлитель, система приостанавливает активность, которая вот-вот начнется? Я не уверен, но любая помощь будет оценена по достоинству. Спасибо – sttaq

+0

также, если я удалю startCatcher, то есть запустите приложение без вашего кода, тогда все будет отлично работать без каких-либо исключений. – sttaq