为什么此JavaFX播放器冻结?

时间:2019-09-07 12:29:33

标签: javafx

我正在尝试使用以下播放器:

public class JavaFXPlayer extends Application {
  private MediaPlayer mediaPlayer;
  private Media media;

  public JavaFXPlayer(String strUrl) {
    this.media = new Media(strUrl);
  }
  public void play() {
    Application.launch();
  }
  @Override
  public void start(Stage primaryStage) throws Exception {
    mediaPlayer = new MediaPlayer(media);

    // by setting this property to true, the audio will be played
    mediaPlayer.setAutoPlay(true);
    primaryStage.setTitle("Playing Audio");
    primaryStage.show();
  }

  @Override
  public void stop() {
    if (mediaPlayer != null) {
      mediaPlayer.stop();
      mediaPlayer.dispose();
    }
  }
}

然后我像这样运行:

JavaFXPlayer player = new JavaFXPlayer(strUrl);
player.play();

但是,当我运行player.play()时,我的整个程序立即冻结。为什么会这样?

1 个答案:

答案 0 :(得分:1)

通过Application#launch启动JavaFX应用程序时,运行时将通过反射为您创建Application子类的实例。这对实现施加了一些限制:

  • 它必须是public类。
  • 它必须具有一个public,无参数的构造函数。
  • 如果使用模块,则必须将其软件包至少导出到javafx.graphics模块。

如果将Application子类用作应用程序的主类,则不需要main方法-至少对于JavaFX 8-12 1 版本而言不需要。如果您有main方法,它应该看起来像这样:

public class MyApp extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception { ... }

}

您还可以将其他一些类的功能用作主类:

public class Main {

    public static void main(String[] args) {
        Application.launch(MyApp.class, args);
    }

}

无论选择哪种方式使用,都必须仍然有一个公共的,无参数的构造函数。这意味着您无法通过构造函数传递Media URL。目前尚不清楚该URL来自何处。如果该URL来自命令行参数,则可以通过Applicationstart(Stage)实例(例如,在init()Application#getParameters()内部)访问这些URL。如果网址是硬编码的,则只需要以其他方式使用它即可(例如,直接在Application子类中使用)。

所有这些,我不确定您的应用为何冻结,因为您没有提供最小的可复制示例。但是,调用Application#launch的线程在该方法调用中被阻塞,直到JavaFX运行时退出为止。这意味着,如果您在上述线程上调用 JavaFX Application线程,则可能会阻塞该方法。


1。 JavaFX具有特殊的处理方式,只要主类是Application的实现,就可以省略main方法。但是,从版本11的JDK中删除JavaFX以后,可能会在以后的版本中删除此功能。

相关问题