我有以下代码:
Task<Integer> task = new Task<Integer>() {
@Override
protected Integer call() throws Exception {
Calendar tajm = Calendar.getInstance();
int hour = tajm.get(Calendar.HOUR_OF_DAY);
int minutes = 0;
updateMessage(Integer.toString(hour));
URL resource = getClass().getResource("classico.mp3");
Media media = new Media(resource.toString());
MediaPlayer mediaPlayer = new MediaPlayer(media);
while (true) {
try {
Thread.sleep(60000);
tajm = Calendar.getInstance();
if (tajm.get(Calendar.HOUR_OF_DAY) != hour) {
hour = tajm.get(Calendar.HOUR_OF_DAY);
updateMessage(Integer.toString(hour));
System.out.println("Hour has changed to: " + hour);
mediaPlayer.play();
} else {
hour = tajm.get(Calendar.HOUR_OF_DAY);
System.out.println("Hour has not changed, it's still: " + hour);
updateMessage(Integer.toString(hour));
}
} catch (InterruptedException ie) {
//System.err.print("...");
}
}
}
};
这首歌只播放一次,第一次改变时。知道为什么吗?
我还有一个问题,不相关: 这是正常的,我的javafx程序开始需要20秒?这有点令人烦恼; p普通的应用程序,只有JavaSE几乎可以立即启动。
答案 0 :(得分:2)
建议的替代方法 - 根据需要创建新播放器
我建议每次要播放mp3时都要创建一个新的MediaPlayer,而不是重复使用现有的MediaPlayer。通过每次创建一个新的MediaPlayer,您只需要在需要时使用媒体播放资源,而不是分配它们并让它们在播放时间之间设置为空闲。
例如,将所有与媒体相关的呼叫一起呼叫而不是在不同的点呼叫,并让垃圾收集器在不再需要时丢弃媒体资源。
Media media = new Media(resource.toString());
MediaPlayer mediaPlayer = new MediaPlayer(media);
mediaPlayer.play();
如何重用现有播放器(如果需要)
如果您确实想要使用当前的代码并重复使用相同的媒体播放器,那么您可以在播放呼叫之前拨打几个电话,以确保在随后的播放呼叫中播放器尝试从头开始播放mp3而不是比结束(导致无操作)。
mediaPlayer.setStartTime(Duration.ZERO);
mediaPlayer.seek(Duration.ZERO);
mediaPlayer.play();
建议 - 定期触发使用时间轴而非任务播放您的mp3
你真的不需要一个单独的线程和任务,这会增加一点复杂性,你可以使用Timeline每小时触发一次游戏事件。
答案 1 :(得分:0)
尝试使用mediaPlayer.playFromStart()
此外:从while循环内部抛出的任何未经检查的异常都将退出程序。作为测试,您可以将当前捕获(InterruptedException)更改为catch(Throwable)并打印错误以查看是否是这种情况。
另一种方法是使用一个被执行的执行器来执行你的任务(参见Javadoc for SceduleThreadPooExecutor)