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

如何在BaseActivity的onPause中停止后台MediaPlayer音乐播放

问题分析

你遇到的核心问题是:BaseActivity中声明的MediaPlayer和MusicPlayer类内部的MediaPlayer是完全独立的两个实例。BaseActivity的onPause方法操作的是自己的player对象,但实际负责播放音乐的是MusicPlayer实例里的player,所以应用进入后台时自然不会暂停音乐。

另外还有个小问题:你的MusicPlayer类没必要继承AppCompatActivity——它只是一个音乐播放工具类,继承Activity会引入不必要的生命周期逻辑,建议去掉这个继承关系。

解决方案

下面提供两种可行的修改方案,你可以根据自己的需求选择:

方案一:单例模式共享MusicPlayer实例

通过单例让全局只有一个MusicPlayer实例,这样BaseActivity可以直接获取到这个实例并调用暂停方法。

1. 修改MusicPlayer类为单例

public class MusicPlayer {
    private static MusicPlayer instance;
    private MediaPlayer player;

    // 私有构造方法,禁止外部直接实例化
    private MusicPlayer() {}

    // 全局获取单例的方法
    public static MusicPlayer getInstance() {
        if (instance == null) {
            instance = new MusicPlayer();
        }
        return instance;
    }

    public void play(Context c, @RawRes int sound) {
        if (player == null) {
            player = MediaPlayer.create(c, sound);
        }
        // 防止重复调用start导致异常
        if (!player.isPlaying()) {
            player.start();
        }
    }

    // 添加暂停方法,供BaseActivity调用
    public void pause() {
        if (player != null && player.isPlaying()) {
            player.pause();
        }
    }

    // 可选:添加资源释放方法,避免内存泄漏
    public void release() {
        if (player != null) {
            player.release();
            player = null;
        }
    }
}

2. 修改BaseActivity

public class BaseActivity extends AppCompatActivity {
    private MusicPlayer musicPlayer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        musicPlayer = MusicPlayer.getInstance();
    }

    @Override
    protected void onPause() {
        super.onPause();
        // 调用单例的暂停方法
        musicPlayer.pause();
    }

    // 可选:在应用退出时释放资源(建议在Application的退出逻辑中调用,而非单个Activity的onDestroy)
    // @Override
    // protected void onDestroy() {
    //     super.onDestroy();
    //     // musicPlayer.release();
    // }
}

3. 修改业务Activity的调用逻辑

// 不再自己new实例,直接获取单例
private MusicPlayer playboy = MusicPlayer.getInstance();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    playboy.play(this, R.raw.song);
}

方案二:通过抽象方法让子类提供MusicPlayer引用

如果不想用单例,可以让BaseActivity定义抽象方法,要求子类返回自己的MusicPlayer实例,统一在BaseActivity中处理暂停逻辑。

1. 修改MusicPlayer类(添加暂停方法)

// 去掉不必要的AppCompatActivity继承
public class MusicPlayer {
    MediaPlayer player;

    public void play(Context c, @RawRes int sound) {
        if (player == null) {
            player = MediaPlayer.create(c, sound);
        }
        if (!player.isPlaying()) {
            player.start();
        }
    }

    public void pause() {
        if (player != null && player.isPlaying()) {
            player.pause();
        }
    }
}

2. 修改BaseActivity为抽象类

public abstract class BaseActivity extends AppCompatActivity {
    @Override
    protected void onPause() {
        super.onPause();
        MusicPlayer musicPlayer = getMusicPlayer();
        if (musicPlayer != null) {
            musicPlayer.pause();
        }
    }

    // 抽象方法,要求子类返回自己的MusicPlayer实例
    protected abstract MusicPlayer getMusicPlayer();
}

3. 修改业务Activity

private MusicPlayer playboy = new MusicPlayer();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    playboy.play(this, R.raw.song);
}

// 实现BaseActivity的抽象方法,返回当前页面的MusicPlayer实例
@Override
protected MusicPlayer getMusicPlayer() {
    return playboy;
}

内容的提问来源于stack exchange,提问作者Takuya2412

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 10:02:32