0

我正在尝试制作一个应用程序来检索图像和 .mp3 文件,并在音频完成后从一个图像转换到下一个图像。我如何在这些图像之间转换的底层框架有点复杂,但我设法在 SWT 中获得了一个动作,它成功地使我能够手动从一个转换到下一个。但是,当我尝试将其自动化时出现了问题。当放入循环时,我的 playAudio() 方法在我在 displayShow() 方法中进行的所有调用都已解决之前开始,这会导致一个空白窗口,尽管音频仍在播放。

这是我要开始显示的操作的运行方法:

            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 并且仍然不能解决我的问题。我错过了什么吗?

4

1 回答 1

0

audioLatch.await()正在阻塞主程序线程,这是所有 SWT 操作都在其上运行的线程,因此可Display.asyncExec运行对象只是排队等待线程可用。

如果您真的必须在该playAudio方法中等待,您可以在那里运行显示事件循环,直到后台线程完成:

while (! background thread finished)
 {
   if (!display.readAndDispatch())
     display.sleep();
 }
于 2014-05-17T07:29:13.123 回答