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

Android开发:如何点击菜单停止按钮终止所有播放的MP3?

解决MediaPlayer无法停止播放的问题

嘿,我看了你的代码,马上就发现问题所在啦!你现在的问题是每个播放按钮都创建了局部的MediaPlayer对象,而类里的成员变量mediaPlayer根本没被赋值——这就导致你点击「停止」按钮时,操作的是一个空对象,自然没法终止正在播放的音频啦。

咱们一步步来修复:

1. 修复播放逻辑:复用成员变量,避免局部变量覆盖

你在action_settings、fav这些选项里,都写了MediaPlayer mediaPlayer = MediaPlayer.create(...),这会创建一个局部变量,和类成员变量mediaPlayer完全是两个独立的对象。播放时用的是局部变量,停止时却去操作未初始化的成员变量,当然起不了作用。

所以播放前,我们要先检查如果之前有正在播放的MediaPlayer,先释放它,再创建新实例赋值给成员变量:

if (id == R.id.action_settings) {
    // 先释放之前的播放器(如果存在)
    releaseMediaPlayer();
    mediaPlayer = MediaPlayer.create(this, R.raw.fon2);
    mediaPlayer.start();
}
if (id == R.id.fav) {
    releaseMediaPlayer();
    mediaPlayer = MediaPlayer.create(this, R.raw.fon2);
    mediaPlayer.start();
}
// 其他播放选项同理修改

2. 完善停止逻辑:增加空值与状态判断

直接调用mediaPlayer.stop()很容易因为对象为空或者已经释放而崩溃,所以我们把释放逻辑抽成一个单独的方法,统一处理:

// 封装播放器释放逻辑
private void releaseMediaPlayer() {
    if (mediaPlayer != null) {
        // 如果正在播放,先停止
        if (mediaPlayer.isPlaying()) {
            mediaPlayer.stop();
        }
        mediaPlayer.release();
        mediaPlayer = null; // 置空,避免后续误操作
    }
}

之后停止按钮的逻辑就可以简化成:

if (id == R.id.stop) {
    releaseMediaPlayer();
}

3. 优化生命周期:避免内存泄漏

在Activity销毁的时候,一定要记得释放MediaPlayer,不然会造成内存泄漏:

@Override
protected void onDestroy() {
    super.onDestroy();
    // 页面销毁时释放播放器
    releaseMediaPlayer();
}

修改后的完整代码

public class DetailActivity extends AppCompatActivity {
    Toolbar mToolbar;
    ImageView mFlower;
    TextView mDescription,mBaslik;
    Button fab;
    MediaPlayer mediaPlayer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_detail);
        mToolbar = findViewById(R.id.toolbar);
        mToolbar.setTitle(getResources().getString(R.string.app_name));
        setSupportActionBar(mToolbar);
        getSupportActionBar().setTitle("MP3 --->");
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            releaseMediaPlayer();
            mediaPlayer = MediaPlayer.create(this, R.raw.fon2);
            mediaPlayer.start();
        } else if (id == R.id.stop) {
            releaseMediaPlayer();
        } else if (id == R.id.fav) {
            releaseMediaPlayer();
            mediaPlayer = MediaPlayer.create(this, R.raw.fon2);
            mediaPlayer.start();
        } else if (id == R.id.yor) {
            releaseMediaPlayer();
            mediaPlayer = MediaPlayer.create(this, R.raw.fon3);
            mediaPlayer.start();
        } else if (id == R.id.asd) {
            releaseMediaPlayer();
            mediaPlayer = MediaPlayer.create(this, R.raw.fon1);
            mediaPlayer.start();
        }
        return super.onOptionsItemSelected(item);
    }

    // 封装播放器释放逻辑
    private void releaseMediaPlayer() {
        if (mediaPlayer != null) {
            if (mediaPlayer.isPlaying()) {
                mediaPlayer.stop();
            }
            mediaPlayer.release();
            mediaPlayer = null;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 页面销毁时释放播放器
        releaseMediaPlayer();
    }
}

这样修改后,不管你点击哪个播放按钮,都会先停止之前的音频(如果有的话)再播放新内容;点击停止按钮时,也能正确释放当前的MediaPlayer,彻底终止播放。

内容的提问来源于stack exchange,提问作者a.dem

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:42:27