在Shutdownhook上使用JavaFX Application.stop()方法
所以我用shutdownhook来清理,bud,因为shutdownhooks线程并不总是可以执行的,我应该把这段代码推到JavaFX应用程序线程(方法stop())上吗?每次我关闭应用程序时,它都会执行?运行代码并不昂贵,基本上只要关闭套接字(如果未关闭)和杀死进程(如果未杀死) 使用Application.stop()在ShutdownHook上进行清理是否是一种良好的做法? 引用文件: 当应用程序应该停止时调用此方法,并提供 方便地准备退出和销毁应用程序 资源。该方法的实现由 应用程序类什么都不做 注意:此方法是在JavaFX应用程序线程上调用的 此方法是否仅用于清理UI的资源?到目前为止,我根本看不出使用shutdownhook over stop()的原因。在Shutdownhook上使用JavaFX Application.stop()方法,java,javafx,Java,Javafx,所以我用shutdownhook来清理,bud,因为shutdownhooks线程并不总是可以执行的,我应该把这段代码推到JavaFX应用程序线程(方法stop())上吗?每次我关闭应用程序时,它都会执行?运行代码并不昂贵,基本上只要关闭套接字(如果未关闭)和杀死进程(如果未杀死) 使用Application.stop()在ShutdownHook上进行清理是否是一种良好的做法? 引用文件: 当应用程序应该停止时调用此方法,并提供 方便地准备退出和销毁应用程序 资源。该方法的实现由 应用程序类什
stop()
只有在通过Platform.exit()
退出应用程序时才会被调用(如果Platform.implicitExit
为true,则最后一个窗口关闭时才会被调用)。如果调用了System.exit()
,或者运行JVM的本机进程被中断(例如,在类似*nix的操作系统上使用ctrl-C),除了通常的退出JavaFX应用程序的方式外,还会执行关闭挂钩
请注意,在调用Application.launch()
之前,在主线程中注册关机挂钩似乎很重要
stop()
在FX应用程序线程上执行,因此可以安全地访问UI元素(例如显示“保存未保存的更改”对话框等)。关机钩子是在后台线程中运行的,因此无法访问UI元素(实际上,FXToolkit可能早就在该阶段停止运行了)
因此,选择取决于用例
为了让这更具体一点,这里有一个快速测试类:
import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class ShutdownTest extends Application {
@Override
public void start(Stage primaryStage) {
Button platformExit = new Button("Platform Exit");
platformExit.setOnAction(e -> Platform.exit());
Button systemExit = new Button("System Exit");
systemExit.setOnAction(e -> System.exit(0));
Button hang = new Button("Hang");
hang.setOnAction(e -> {while(true);});
HBox root = new HBox(5, platformExit, systemExit, hang);
root.setPadding(new Insets(20));
root.setAlignment(Pos.CENTER);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
@Override
public void stop() {
System.out.println("Stop");
}
public static void main(String[] args) {
Runtime.getRuntime().addShutdownHook(new Thread(() -> System.out.println("Shutdown hook")));
launch(args);
}
}
我在MacOSX上测试了这个
通过“平台退出”按钮退出、关闭窗口或右键单击Dock并选择“退出”将执行stop()
方法和关闭挂钩
通过“系统退出”按钮退出,通过强制流程从“活动监视器”退出,或通过命令行中的kill id
终止流程,将仅执行关闭挂钩。通过按下“挂起”按钮挂起应用程序,然后右键单击Dock并选择“强制退出”可以得到相同的结果
通过向进程发送SIGKILL退出(
kill-9id
或从命令行发送kill-SIGKILL id
)既不执行stop()
方法,也不执行关机钩子。这个答案让我想知道我是否会使用stop()关闭一些重要的资源,因为我可以强制终止我的进程,而且我看到它根本没有被调用,所以崩溃可能也是如此。感谢您的快速回答。@TomasBisciak绝大多数JavaFX应用程序都不会调用System.exit()
(您应该总是喜欢Platform.exit()
),并且不会从命令行运行(减少中断的可能性),所以通常stop()
就足够了。但同样,这取决于您的用例。