2

後でアクティビティで再生できるようにサウンドをロードしようとしています。onCreate を終了する前にロードが完了していることを確認したいと考えています (場合によっては、Handler メソッドによってすぐに再生されることもあります。

サウンドをすぐに再生しようとすると、「サンプル 1 の準備ができていません」というエラーが頻繁に発生します。

だから私は答えを探しに行きました、そしてほとんどの人が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

これを Asus Nexus 7 (android 4.2.1) と Samsung Galaxy S3 (android 4.0.4) で実行しています。

ありがとうケビン

4

2 に答える 2

1

Thread.sleep(1000);の関数のこの行は、play_sound() 実際にはメイン スレッド(UI Thread)をブロックしています。

于 2012-12-16T07:10:08.810 に答える
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() を呼び出したくありません。

于 2014-03-01T08:40:07.103 に答える