【发布时间】:2016-06-27 16:28:34
【问题描述】:
在我的 JavaFX 应用程序中,我想在出现意外异常时显示错误对话框并退出应用程序。所以在我的主要方法中,我在启动应用程序之前设置了一个默认的未捕获异常处理程序:
setDefaultUncaughtExceptionHandler((thread, cause) -> {
try {
cause.printStackTrace();
final Runnable showDialog = () -> {
// create dialog and show
};
if (Platform.isFxApplicationThread()) {
showDialog.run();
} else {
runAndWait(showDialog);
}
} catch (Throwable t) {
// ???
} finally {
System.exit(-1);
}
});
launch(MyApp.class);
说明:当未捕获的异常处理程序在 JavaFX 应用程序线程 (FXAT) 上执行时,我只运行用于显示对话框的代码。当 FXAT 不调用异常处理程序时,这当然不起作用。在这种情况下,我必须将代码推送到 FXAT。但我不能使用Platform.runLater,因为这样我的应用程序就会在显示对话框之前退出。所以,我创建了自定义方法runAndWait,它在内部通过Platform.runLater 推送runnable,但一直等到runnable 的执行(带有一些倒计时锁存机制)。
现在的问题是:当我的 start() 方法中发生异常时,我的应用程序就会卡住。因为它试图等到执行显示的对话框,但 FXAT 从不执行此操作。我猜这是因为当 start() 方法因异常而失败时,FXAT 就死了?我不确定这是否是 start() 方法的特殊情况,或者当异常被抛出并且未在 FXAT 执行的代码中捕获时,这是否会在任何情况下发生。
据我所知,在 Swing 中,EDT 是一个由多个线程组成的复杂架构。当 EDT 上的某些执行失败时,并不是整个 Swing 都崩溃了。但这似乎是发生了什么?
那么我可以在这里做什么?如何向用户显示应用程序无法启动?
【问题讨论】:
-
“我不能使用
Platform.runLater(),因为这样我的应用程序会在对话框显示之前退出”。打电话Platform.setImplicitExit(false);能解决这个问题吗? -
不,当然不是。应用程序退出的原因是我的异常处理程序中的 System.exit() 调用。
-
等等,我是个白痴。程序退出太早忘记这一点。因为我也可以在 Runnable 中为 FX 线程移动 System.exit 调用。但是,当 start 方法抛出异常时,我仍然无法在 FX 线程上运行任何东西。
-
我假设
runAndWait()被阻塞直到可运行对象完成,这将阻止System.exit(...)被调用。您能否创建一个minimal reproducible example 来说明外汇平台因start()方法中的异常而关闭? -
刚刚试验了一下jvisualvm,好像在start方法出现异常时FX Application Thread就退出了。我看不出有什么办法……
标签: javafx uncaughtexceptionhandler