我正在使用此代码来处理任何可能导致我的应用程序崩溃的未捕获异常。
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);
}
}
当我运行它时出现已知但未捕获的异常(只是为了测试), Activity “CrashActivity”被调用,但必须在它出现之前出现的 Toast 没有出现。
实际上我只想显示 Toast 然后调用 myContext.finish();而不是去 CrashActivity。但是那个 toast 是看不见的。
我哪里错了?
最佳答案
在谷歌搜索完全相同的问题时发现了这个问题。
据我所知,只要存在应用程序上下文,就没有必要从 UI 线程调用 Toast.show()
。
AFAIK:此处出现的问题如下:您尝试显示 Toast,之后您的应用程序立即被 VM 关闭,这意味着您的 Toast 也被关闭。
问题的解决方案如下:
- 从单独的线程运行 Toast
- 在未捕获的异常处理程序中延迟关闭您的应用程序。
我的做法是:
在 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.
}
}
});
它类似于 ACRA 中的 Toast 通知的工作方式(实际上这是我从中得到提示的地方)。
关于android - Toast 未出现在 UnCaughtExceptionHandler 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11609640/