You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

重置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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:11:06