8

Я использую этот код для обработки любых неперехваченных исключений, которые могут привести к сбою моего приложения.Тост не отображается в UnCaughtExceptionHandler

public class ExceptionHandler implements java.lang.Thread.UncaughtExceptionHandler { 
    private final Context myContext; 

    public ExceptionHandler(Context context) { 

     myContext = context; 
    } 

    public void uncaughtException(Thread thread, Throwable exception) { 

     Toast.makeText(myContext, 
       "The application has crashed, and a report is sent to the admin", 
       Toast.LENGTH_SHORT).show(); 
     StringWriter stackTrace = new StringWriter(); 
     exception.printStackTrace(new PrintWriter(stackTrace)); 
     System.err.println(stackTrace);// You can use LogCat too 
     Intent intent = new Intent(myContext, CrashActivity.class); 
     myContext.startActivity(intent); 
     Process.killProcess(Process.myPid()); 
     System.exit(10); 
    } 
} 

Когда я запустить его с известным, но неперехваченным исключением (только для проверки), активность «CrashActivity» называется, но Toast, который должен предстать перед ним не появляются.

На самом деле я хотел показать только тост, а затем вызвать myContext.finish(); вместо перехода в CrashActivity. Но этот тост не видно.

Где я ошибаюсь?

+2

Я не программист для Android, но из чтения, которое я сделал, не нужно ли вызывать тосты в потоке пользовательского интерфейса? В этом случае вы вызываете его в потоке пользовательского интерфейса? Думаю, вы, наверное, уже об этом подумали. –

+0

да, вы правы .. я не называю тост по ui нить :( –

ответ

3

Вы, вероятно, вызывая Тост из потока в то время как тост должен быть вызван из потока пользовательского интерфейса ...

Если это не помогает, пожалуйста, предоставьте нам выход LogCat так что мы можем увидеть, какие ошибка, которую вы получаете.

+0

Да, я ошибаюсь в использовании тоста в другом потоке. Фактически я видел это в приложении, где, когда приложение падает, отображается тост на То, что он на самом деле вызывает одно и то же действие, а затем показывает тост? –

7

Обнаружил этот вопрос во время поиска по поиску по той же проблеме. Насколько я могу судить, нет необходимости вызывать Toast.show(), вызванный из потока пользовательского интерфейса, пока существует контекст приложения.

AFAIK: Проблема, которая возникает здесь, заключается в следующем: вы пытаетесь показать Toast, и сразу после этого приложение закрывается VM, что означает, что ваш Toast также выключается.

Решение для проблемы заключается в следующем:

  • Запуск Тост из sepearate Тема
  • Задержка выключения вашего приложения в неперехваченным Exception Handler.

Что я делаю следующее:

В Application::onCreate():

Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() { 
    @Override 
    public void uncaughtException(Thread thread, Throwable ex) 
    { 
     new Thread() { 
      @Override 
      public void run() { 
       Looper.prepare(); 
       Toast.makeText(getApplicationContext(), "Application crashed", Toast.LENGTH_LONG).show(); 
       Looper.loop(); 
      } 
     }.start(); 

     try 
     { 
      Thread.sleep(4000); // Let the Toast display before app will get shutdown 
     } 
     catch (InterruptedException e) 
     { 
      // Ignored. 
     } 
    } 
}); 

Это похоже на то, как уведомление Toast в ACRA работает (на самом деле это то, где я получил намек от) ,

+0

Это было именно то, что мне было нужно, так как мне нужен быстрый (временный) способ увидеть некоторые детали исключения. Я обнаружил, что мне также пришлось положить в вызове 'System.exit()' после блока 'catch'.Это отсутствует в приведенном выше? – darrenp

+0

Pjuh. Хороший вопрос. Я не выхожу с 'System.exit()', но использую обработчик исключений по умолчанию с '_androidDefaultUncaughtExHandler.uncaughtException (thread, ex);' и устанавливая его с помощью '_androidDefaultUncaughtExHandler = Thread.getDefaultUncaughtExceptionHandler();' – GeneSys

+1

Имеет смысл. Обработчик исключений по умолчанию должен убирать и вызывать 'System.exit()'. – darrenp

3

Вызов System.exit(0) с Android UncaughtExceptionHandler помогает приложению восстанавливаться после ошибки и перезапускать последнюю активность. IMHO, пользовательский опыт значительно улучшился. Однако этот подход необходимо проверять и тестировать на нескольких платформах Android. Попробовали это на GB и JB. Он работал нормально. Кроме того, я слышал от других (я новичок в Android), что вызов System.exit() не рекомендуется в Android, но .. мог бы использовать это как хороший вариант восстановления для сбоев приложений для Android.

public void uncaughtException(Thread thread, Throwable ex) { 
     new Thread() { 
      @Override 
      public void run() { 
       Looper.prepare(); 
       Toast.makeText(YourActivity.this, "Application has Crashed. Recovering now.", Toast.LENGTH_LONG).show(); 
       /* Log relevant message/analytics from here. */ 
       System.exit(1); 
       Looper.loop(); 
      } 
     }.start(); 
    } 
+0

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

+0

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