我正在使用此代码来处理任何可能导致我的应用程序崩溃的未捕获异常。
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才会显示。
实际上我只想显示Toast,然后调用myContext.finish();而不是去CrashActivity。但那种敬酒不可见。
我哪里错了?
答案 0 :(得分:8)
在Google上搜索完全相同的问题时发现了这个问题。
据我所知,只要存在应用程序上下文,就没有必要从UI线程调用Toast.show()
。
AFAIK:此处出现的问题如下:您正在尝试显示Toast,之后您的应用程序会立即被VM关闭,这意味着您的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通知如何工作(实际上这是我从中得到提示的地方)。
答案 1 :(得分:4)
从Android System.exit(0)
中调用UncaughtExceptionHandler
可帮助应用程序从错误中恢复并重新启动上一个活动。恕我直言,用户体验得到显着改善。但是,这种方法需要在多个Android平台上进行尝试和测试。在GB和JB上试过这个。它工作正常。另外,我从其他人那里听到(我是Android的新手),在Android中不建议调用System.exit()
但是......可以使用它作为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();
}
答案 2 :(得分:3)
您可能正在从线程调用Toast,而应该从UI线程调用Toast ...
如果这没有帮助,请向我们提供logcat输出,以便我们可以看到您遇到的错误。