2012-12-16 112 views
2

我想,這樣它可將在我的活動後發揮到加載聲音,我想,以確保它完成加載之前,我完成的onCreate(有時它會起到相當多立刻被處理方法。SoundPool.OnLoadCompleteListener被封鎖

我經常得到錯誤「樣品1沒有準備好」,如果聲音要馬上播放。

所以我去尋找答案,而且幾乎每個人都在說使用SoundPool.OnLoadCompleteListener,但我試過了,它似乎並沒有做什麼有用的東西。這就像它等待我的onCreate方法以及其他一切去完成它被調用之前,所以如果我試圖讓我的onCreate西澳它爲onLoadComplete調用然後沒有任何反應。下面是一個簡單的測試程序來演示(請注意,在實際的程序中,play_sound()的調用不會在onCreate中,它會從其他地方調用,但可能會很快)。

下面的程序是從logcat的輸出的日誌文件。

如果我註釋掉所有與OnLoadCompleteListener和同時(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(安卓4.2.1)上運行這一點,也是三星Galaxy S3(安卓4.0.4)

謝謝 凱文

+0

嘗試在新的線程來播放聲音。 –

回答

1

此行Thread.sleep(1000);play_sound()功能實際上是阻止你的主線程(UI線程)

+0

也許我的設計是在錯誤的方向前進了,但我的想法是,有必要阻塞主線程,以便給予的Soundpool機會完成加載聲音,迎頭趕上。還是我完全錯過了聽衆的觀點? -http: –

+0

您更好地使用聲音池前看到這//www.vogella.com/articles/AndroidMedia/article.html –

+0

你應該不會阻止你的UI線程做一些事情,可以在後臺完成。 – JoxTraex

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()。

+0

我想我吹了那一個。我不認爲你需要onLoadComplete中的sounds.load(),但是你需要play_sound()。 – Hutch