Using JavaFX Application.stop() method over Shutdownhook

后端 未结 1 1825
长发绾君心
长发绾君心 2020-12-10 13:24

So im using shutdownhook to clean up, bud since its not always guaranteed that shutdownhooks thread executes , should i just push this code onto JavaFX Application Thread (m

相关标签:
1条回答
  • 2020-12-10 14:21

    stop() will only be called if you exit the application via Platform.exit() (or when the last window is closed if Platform.implicitExit is true). Shutdown hooks will execute if System.exit() is called, or if the native process running the JVM is interrupted (e.g. ctrl-C on a *nix-like OS), in addition to the usual way of exiting a JavaFX Application.

    Note that it appears to be important to register the shutdown hook in the main thread, before calling Application.launch().

    stop() is executed on the FX Application Thread, so it is safe to access UI elements (e.g. to show "save unsaved changes" dialogs, etc). Shutdown hooks are run in a background thread, so cannot access UI elements (indeed the FX Toolkit will probably long have stopped running by that stage).

    So the choice depends on the use case.

    To make this a little more concrete, here's a quick test class:

    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);
        }
    }
    

    I tested this on Mac OS X.

    Exiting via the "Platform Exit" button, by closing the window, or by right-clicking on the Dock and choosing "Quit" will execute both the stop() method and the shutdown hook.

    Exiting by the "System Exit" button, by forcing the process to quit from "Activity Monitor", or by killing the process by kill id from the command line, will execute the shutdown hook only. Hanging the application by pressing the "Hang" button and then right-clicking on the Dock and choosing "Force Quit" has the same result.

    Exiting by sending a SIGKILL to the process (kill -9 id or kill -SIGKILL id from the command line) executes neither the stop() method nor the shutdown hook.

    0 讨论(0)
提交回复
热议问题