简体   繁体   中英

MediaPlayer or SoundPool for multiple short sounds?

The app basically allows the user to play an animal sound, voice or other sound when clicking various items. I'm trying to figure out if I'm doing this in the right way because I'm seeing some issues like this error, when the user mutes>unmutes>plays a sound:

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;
    ...
}

Here's an example of how I am using 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;
            }
        });
    }

I'm doing this multiple times for different buttons etc, making sure to release() after they are done since I ran into mem issues before. So the exception is telling above is telling me isPlaying() isn't valid since MediaPlayer does not exist but for some reason it ignores if(mMediaPlayer != null)

It is necessary to stop if anything is playing since the user is free to click randomly and of course I do not want any sounds overlaying eachother.

Here's how the user mutes:

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;

I very much appreciate any help with this, thanks a lot!

If you has not so much tracks to play (not more than 32) you can try to initialize multiple MediaPlayer instances and release() them only when app onPause()/onStop() called. Then you will have pool of ready to use MediaPlayer's . You just have to remember which one is in use right now.

Also if you use MediaPlayer in multiple threads (not only UI thread) then you MUST use mutex (thread blocking) to avoid issues.

MediaPlayer based state machine - IllegalStateException basicly means player instance is in state when calling isPlaying() not allowed. For isPlaying() documented not allowed state is only Error state, but assume state after calling release() may be also not appropriate for this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM