如何安排后台线程在我的应用中播放声音?

时间:2012-04-13 22:33:23

标签: java android multithreading

我有一个应该对某些事件作出反应的过程。所以当调用playFromList()时,它会从soundpool播放一些声音。然后在一个线程中我设置了一个标志,并且持续3.5秒它不应该播放任何声音。

我得到的是:它播放声音,而不是等待3.5秒。如果playFromList()在3.5秒内被调用5次,它仍然会到达SoundManager.playSound(listNr),并且仍然会在17.5秒内完成。它不完全是我想要的。我希望方法SoundManager.playSound(listNr)只调用一次。

public class Settings{
    public static boolean flag = false;
}

 public class Main{
 public void playFromList(int listNr,int g){

        if(!Settings.flag){
            SoundManager.playSound(listNr);
            if(g ==0){
                mpVolume((float) 0.3);
                t5sec.run();
            }else{pauseMus();}      
        }           
    }

        private Handler vijfSeconden = new Handler(){
            public void handleMessage(Message msg){
                mpVolume((float)0.8);
            }
        };
        Thread t5sec = new Thread(){
            public void run(){
                if(Settings.flag == false){
                    Settings.flag = true;
                    try {
                        Thread.sleep(3500); 
                    } catch (InterruptedException e) {
                        Settings.flag = false;
                        e.printStackTrace();
                    }
                    vijfSeconden.sendEmptyMessage(0);

                    Settings.flag = false;
                }
            }
        };
 }

1 个答案:

答案 0 :(得分:0)

代码几乎没有问题。可能最重要的是奇怪的是 t5sec.run(),在Java中你应该在Thread对象上使用start方法来启动新的Thread。如上所述,它将在调用线程中执行。 第二个问题是绝对缺乏同步,我想,解决这个问题的一种方法是在Settings.flag中使用AtomicBoolean而不是boolean

另一个问题是每次启动新线程都非常昂贵。从描述中准确地说出你想要做什么有点难,但如果我的理解是正确的,你应该做这样的事情:

if ( (System.currentTimeInMillis() - lastTimePlayed) < 3500) {
 playSound();
 lastTimePlayed = System.currentTimeInMillis();
}

就是这样,不需要线程。如果您希望您的类是线程安全的,您可能希望使用AtomicInteger来保存lastTimePlayed值。