重置MediaPlayer后如何准备音频?音效板应用重放问题求助
解决MediaPlayer首次播放后无法再次播放的问题
嘿,我太懂你遇到的这个小麻烦了!你的代码里用MediaPlayer.create()创建了音效实例,第一次播放没问题,但播放完重置后再点击就没反应了对吧?这是因为MediaPlayer.create()的特殊性——它帮你自动完成了prepare()操作,但播放结束后,MediaPlayer会进入Completed状态,要是调用了reset(),它会回到Idle状态,这时候直接start()肯定行不通,得重新绑定数据源并准备才行。
给你两种实用的解决方案,按需选择:
方案一:每次播放都创建新的MediaPlayer实例
这种方法简单直接,适合音效文件不大的场景,每次点击都新建实例,播放完就释放资源,避免内存占用:
Button play_SoundOne = (Button) findViewById(R.id.play_SoundOne); play_SoundOne.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 每次点击都生成新的MediaPlayer实例 MediaPlayer soundOne = MediaPlayer.create(MainActivity.this, R.raw.somesound); soundOne.start(); // 播放完成后立刻释放资源,防止内存泄漏 soundOne.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { mp.release(); } }); } });
方案二:复用MediaPlayer实例(适合频繁播放的场景)
如果这个音效需要频繁播放,反复创建实例有点浪费性能,那可以复用同一个实例,在播放完成后提前准备好下一次播放:
private MediaPlayer soundOne; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化MediaPlayer soundOne = MediaPlayer.create(this, R.raw.somesound); Button play_SoundOne = (Button) findViewById(R.id.play_SoundOne); play_SoundOne.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (!soundOne.isPlaying()) { // 如果已经播放过,先回到开头;如果是首次或重置后,重新准备 if (soundOne.getCurrentPosition() > 0) { soundOne.seekTo(0); } else { try { soundOne.prepare(); } catch (IOException e) { e.printStackTrace(); } } soundOne.start(); } } }); // 播放完成后重置并重新绑定数据源 soundOne.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { mp.reset(); try { // 重新设置raw资源的数据源 AssetFileDescriptor afd = getResources().openRawResourceFd(R.raw.somesound); mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); afd.close(); mp.prepare(); } catch (IOException e) { e.printStackTrace(); } } }); } // 别忘了在Activity销毁时释放资源! @Override protected void onDestroy() { super.onDestroy(); if (soundOne != null) { soundOne.release(); soundOne = null; } }
为什么你的原代码不行?
你用MediaPlayer.create()创建的实例,播放完成后会进入Completed状态,要是调用了reset()(或者某些场景下系统自动处理),它会回到Idle状态,这时候MediaPlayer已经没有绑定任何数据源了,直接调用start()当然没反应。必须重新设置数据源并调用prepare()/prepareAsync(),才能再次播放。
另外,不管用哪种方案,都要记得在合适的时机(比如Activity销毁)释放MediaPlayer资源,不然容易造成内存泄漏哦!
内容的提问来源于stack exchange,提问作者Johny strawits
相关产品推荐
相关产品推荐

