stop()
只有在通过Platform.exit()
退出应用程序时调用(或者如果Platform.implicitExit
为true,则在关闭最后一个窗口时)。如果调用System.exit()
,或者如果运行JVM的本地进程被中断(例如在*nix-like OS上按下ctrl-C),则会执行关闭挂钩,除了通常的JavaFX应用程序退出方式。
请注意,在调用Application.launch()
之前在主线程中注册关闭挂钩似乎很重要。
stop()
在FX Application线程上执行,因此可以安全地访问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()
方法也不会执行关闭挂钩。
System.exit()
(您应该始终优先选择Platform.exit()
),也不是从命令行运行的(减少了被中断的可能性),因此通常stop()
就足够了。但这还取决于您的使用情况。 - James_D