我正在尝试创建一个应用程序,在音频完成后检索图像和.mp3文件并从一个图像转换到下一个图像。我在这些图像之间转换的基础框架有点复杂,但我已经设法在SWT中获得一个动作,成功地使我能够手动从一个转换到下一个。但是,当我试图将其自动化时,出现了一个问题;当放入循环时,我的playAudio()方法在我在displayShow()方法中进行的所有调用都已解决之前开始,这导致一个空白窗口,尽管音频仍在播放。
以下是我要开始演出的动作的run方法:
Action startAction = new Action("Start") {
public void run() {
//do {
displayShow();
playAudio();
//} while(true);
}
};
这是playAudio()。我能够轻松播放音频:
public void playAudio() {
final String audio = "Happy_Birthday.mp3";
audioLatch = new CountDownLatch(1);
audioThread = new Thread() {
public void run() {
try {
Player player = new Player
(new BufferedInputStream
(new FileInputStream(audio)));
player.play();
audioLatch.countDown();
} catch (JavaLayerException e) {
} catch (FileNotFoundException e) {
} catch (Exception e) {
}
}
};
audioThread.start();
try {
audioLatch.await();
} catch (InterruptedException e) {
}
}
这是displayShow():
private void displayShow() {
new Thread() {
public void run() {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
Control[] children = container.getChildren();
for (int i = 0; i < children.length; i++) {
children[i].dispose();
}
show.showSlide(container);
container.layout();
}
});
}
}.start();
}
show.showSlide返回一个复合体,其父元素是容器,它是最高父元素组合的直接子元素。在新创建的合成中,图像将添加到标签,标签的父级将分配给复合。我意识到displayShow()是否在一个单独的线程中似乎是无关紧要的;这只是我尝试过的最后一件事。
不仅仅是添加了导致刷新不执行的循环。我可以让手动转换工作的唯一方法是从playAudio()方法中删除CountDownLatch。如果我要删除这个锁存器,在循环中包含这两个方法的唯一方法是嵌入while循环,这似乎占用了相当多的CPU但仍然无法解决我的问题。我错过了什么吗?
答案 0 :(得分:0)
audioLatch.await()
阻塞主程序线程,这是所有SWT操作都运行的线程,因此Display.asyncExec
runnables只是排队,直到线程可用。
如果你真的必须在playAudio
方法中等待,你可以在那里运行显示事件循环,直到后台线程结束:
while (! background thread finished)
{
if (!display.readAndDispatch())
display.sleep();
}