SoundPool.OnLoadCompleteListener被阻止

时间:2012-12-16 07:02:02

标签: android soundpool

我正在尝试加载一个声音,以便以后可以在我的活动中播放,我想确保它在我完成onCreate之前已经完成加载(有时它会立即由​​一个处理程序播放方法

如果要立即播放声音,我经常会收到错误“sample 1 not READY”。

所以我去寻找答案,几乎每个人都说要使用SoundPool.OnLoadCompleteListener,但是我试过了,但似乎并没有做任何有用的事情。这就像它等待我的onCreate方法和其他一切在调用之前完成,所以如果我尝试让我的onCreate等待onLoadComplete调用,那么没有任何反应。

下面是一个简单的测试程序来演示(请注意,在真实程序中,对play_sound()的调用不会在onCreate中,它将从其他地方调用,但可能非常快)。

程序下面是LogCat的日志文件输出。

如果我注释掉与OnLoadCompleteListener和while(sound_loaded)循环相关的所有内容,而只是放入一个'SystemClock.sleep(100)',它几乎完美无缺,但这感觉就像是作弊。

public class MainActivity extends Activity {
private static HashMap<Integer, Integer> soundMap;
private SoundPool sounds;
private boolean sound_loaded = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Log.d(getClass().getSimpleName(), "onCreate started");

    sounds = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
    soundMap = new HashMap();
    Log.d(getClass().getSimpleName(), "Loading sound");

    sounds.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
        public void onLoadComplete(SoundPool sp, int sid, int status) {
            Log.d(getClass().getSimpleName(), "Sound is now loaded");
            sound_loaded = true;
    }});

    soundMap.put(1, sounds.load(this, R.raw.ping_da_ding_ding_ding, 1));
    //SystemClock.sleep(100);
    play_sound();

    Log.d(getClass().getSimpleName(), "onCreate Finished");
}

public void play_sound() {
    int loop_counter = 0;   
    while (sound_loaded == false) { 
        if (loop_counter++ > 3) {
            Log.d(getClass().getSimpleName(), "Looped too many times, breaking out!");
            break;
        }
        Log.d(getClass().getSimpleName(), "sleeping waiting for sound");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();}
    }   

    int sound_stream = sounds.play(soundMap.get(1), 0.5f, 0.5f, 0, 0, 1);
}

日志输出

 12-16 17:55:13.025: D/MainActivity(22322): onCreate started
 12-16 17:55:13.030: D/MainActivity(22322): Loading sound
 12-16 17:55:13.035: D/MainActivity(22322): sleeping waiting for sound
 12-16 17:55:13.045: V/MediaPlayer(22322): decode(55, 753, 5391)
 12-16 17:55:14.035: D/MainActivity(22322): sleeping waiting for sound
 12-16 17:55:15.035: D/MainActivity(22322): sleeping waiting for sound
 12-16 17:55:16.035: D/MainActivity(22322): sleeping waiting for sound
 12-16 17:55:17.035: D/MainActivity(22322): Looped too many times, breaking out!
 12-16 17:55:17.045: I/Reverb(22322):  getpid() 22322,  IPCThreadState::self()->getCallingPid() 22322
 12-16 17:55:17.050: D/MainActivity(22322): onCreate Finished
 12-16 17:55:17.120: D/(22322): Sound is now loaded

我在华硕Nexus 7(android 4.2.1)以及三星Galaxy S3(android 4.0.4)上运行这个

由于 凯文

2 个答案:

答案 0 :(得分:1)

Thread.sleep(1000);函数中的这一行play_sound()实际上阻止了你的主线程(UI线程)

答案 1 :(得分:0)

我认为你需要这样做:

sounds.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
    public void onLoadComplete(SoundPool sp, int sid, int status) {
        Log.d(getClass().getSimpleName(), "Sound is now loaded");
        sound_loaded = true;
        soundMap.put(1, sounds.load(this, R.raw.ping_da_ding_ding_ding, 1));
        play_sound();
        Log.d(getClass().getSimpleName(), "onCreate Finished");
    }
});

目前,您正在设置OnLoadCompleteListener ...并立即调用play_sound()。在OnLoadComplete()触发之前,您不想调用play_sound()。