MediaPlayer 或 SoundPool 用于多个短声音?

Posted

技术标签:

【中文标题】MediaPlayer 或 SoundPool 用于多个短声音?【英文标题】:MediaPlayer or SoundPool for multiple short sounds? 【发布时间】:2014-12-05 03:03:43 【问题描述】:

该应用程序基本上允许用户在单击各种项目时播放动物声音、声音或其他声音。我试图弄清楚我是否以正确的方式执行此操作,因为当用户静音>取消静音>播放声音时,我看到了类似此错误的一些问题:

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;
            
        );
    

我为不同的按钮等多次执行此操作,确保在完成后释放(),因为我之前遇到过内存问题。所以上面的异常告诉我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】:

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

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

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

【讨论】:

以上是关于MediaPlayer 或 SoundPool 用于多个短声音?的主要内容,如果未能解决你的问题,请参考以下文章

Android - MediaPlayer/SoundPool 性能?

android中常见声音操作方式(Ringtone,SoundPool,MediaPlayer)小结

Android中的音频处理------SoundPool,MediaRecorder,MediaPlayer以及RingStone总结

如何使用 Android 动画播放“滴答滴答”声音(可能使用“Android MediaPlayer / SoundPool”)?

Android Studio 中的 SoundPool 到 MediaPlayer

SoundPool 和 MediaPlayer 音量对应问题