Тост не отображается в 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. Но этот тост не виден.
Где я не прав?
3 ответа
Вы, вероятно, вызываете Toast из потока, в то время как toast следует вызывать из потока UI...
Если это не помогает, предоставьте нам выходные данные logcat, чтобы мы могли видеть, какую ошибку вы получаете.
Нашел этот вопрос, пока гуглил точно такую же проблему. Насколько я могу сказать, нет необходимости иметь Toast.show()
вызывается из потока пользовательского интерфейса, пока существует контекст приложения.
AFAIK: Проблема, которая здесь возникает, заключается в следующем: вы пытаетесь показать Toast, и сразу после этого ваше приложение закрывается виртуальной машиной, что означает, что ваш Toast также выключен.
Решение проблемы заключается в следующем:
- Запустите тост из отдельной темы
- Задержка закрытия вашего приложения в обработчике исключений Uncaught.
Я делаю следующее:
В 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 (на самом деле это то, откуда я получил подсказку).
Призвание System.exit(0)
из Android UncaughtExceptionHandler
помогает приложению восстановиться после ошибки и перезапустить последнюю активность. ИМХО, пользовательский опыт значительно улучшается. Тем не менее, этот подход должен быть опробован и протестирован на нескольких платформах 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();
}