使用Application.stop()来清理ShutdownHook是一种好习惯吗?
来自doc的引用:
This method is called when the application should stop,and provides a
convenient place to prepare for application exit and destroy
resources. The implementation of this method provided by the
Application class does nothing.NOTE: This method is called on the JavaFX Application Thread.
此方法仅用于清理UI的资源吗?到目前为止,我根本没有看到使用shutdownhook over stop()的原因.
解决方法
在FX应用程序线程上执行stop(),因此访问UI元素是安全的(例如,显示“保存未保存的更改”对话框等).关闭挂钩在后台线程中运行,因此无法访问UI元素(事实上FX Toolkit可能很久就会停止在该阶段运行).
所以选择取决于用例.
为了使这更具体,这是一个快速测试类:
- 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);
- }
- }
我在Mac OS X上测试了这个.
通过“平台退出”按钮退出,关闭窗口,或右键单击Dock并选择“退出”将同时执行stop()方法和关闭钩子.
通过“系统退出”按钮退出,通过强制进程从“活动监视器”退出,或者通过命令行中的kill id终止进程,将仅执行关闭挂钩.通过按“挂起”按钮然后右键单击Dock并选择“强制退出”来挂起应用程序具有相同的结果.
通过向进程发送SIGKILL退出(从命令行kill -9 id或kill -SIGKILL id)既不执行stop()方法也不执行shutdown hook.