MediaPlayer或SoundPool用于多种短音?

时间:2014-12-05 03:03:44

标签: java android android-mediaplayer soundpool

该应用程序基本上允许用户在点击各种项目时播放动物声音,声音或其他声音。我试图弄清楚我是否以正确的方式做这件事,因为我看到了一些像这个错误的问题,当用户静音>取消静音>播放声音时:

java.lang.IllegalStateException at android.media.MediaPlayer.isPlaying(Native Method)

public class GuessActivity extends Activity implements PopupMenu.OnMenuItemClickListener {
    public static int[] ssSoundsArray = {R.raw.sbuffalo, R.raw.scamel, R.raw.scat, R.raw.schicken};
    public static int[] ssVoicesArray = {R.raw.buffalo, R.raw.camel, R.raw.cat, R.raw.chicken};
    MediaPlayer mMediaPlayer;
    Context context;
    ...
}

以下是我如何使用MediaPlayer的示例:

    if(audio_all) {
        if(mMediaPlayer != null) {
            if(mMediaPlayer.isPlaying()) {
                mMediaPlayer.stop();
                mMediaPlayer.release();                
            }
        }

        mMediaPlayer = MediaPlayer.create(this, R.raw.whatever);
        mMediaPlayer.start();
        mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            public void onCompletion(MediaPlayer mediaPlayer) {
                mMediaPlayer.release();
                mMediaPlayer = null;
            }
        });
    }

我为不同的按钮等多次这样做,确保在完成之后释放(),因为我之前遇到过mem问题。因此上面的例外情况告诉我isPlaying()无效,因为MediaPlayer不存在但由于某种原因它忽略了if(mMediaPlayer != null)

如果有任何内容正在播放是必要的,因为用户可以随意点击,当然我不希望任何声音相互叠加。

以下是用户如何静音:

case R.id.action_toggle_sounds:
            if(audio_all) {

                if(mMediaPlayer != null) {
                   if(mMediaPlayer.isPlaying()) {
                   mMediaPlayer.stop();
                   mMediaPlayer.release();                
                   }
                }

                Toast.makeText(this,"All sounds disabled",Toast.LENGTH_LONG).show();
                audio_all = false;
            } else {
                Toast.makeText(this,"All sounds enabled",Toast.LENGTH_LONG).show();
                audio_all = true;
            }
            return true;

非常感谢任何帮助,非常感谢!

1 个答案:

答案 0 :(得分:1)

如果您没有太多的曲目可以播放(不超过32个),您可以尝试初始化多个MediaPlayer个实例,并仅在调用app onPause()/ onStop()时释放它们。 然后,您将拥有可以使用的池MediaPlayer's。你只需要记住现在正在使用哪一个。

此外,如果您在多个线程(不仅是UI线程)中使用MediaPlayer,那么您必须使用互斥(线程阻塞)来避免问题。

基于MediaPlayer的状态机 - IllegalStateException基本上意味着当不允许调用isPlaying()时,播放器实例处于状态。对于isPlaying()记录的不允许状态仅为Error状态,但在调用release()后假设状态可能也不适合此。