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

Android重复播放音频时出现E/MediaPlayer: error (1, -19)问题求助

解决MediaPlayer错误(1,-19):按钮点击音效播放问题

这个E/MediaPlayer: error (1, -19)错误本质是MediaPlayer状态管理混乱导致的,你的代码里有几个关键问题:

  1. 你在OnCreate里提前初始化了mSound = new MediaPlayer(),但点击事件里又重复new MediaPlayer(),还混合了MediaPlayer.create()(这个方法本身会返回一个已经初始化好的MediaPlayer实例,不需要额外new),导致对象状态冲突。
  2. 每次点击时的stop()->reset()->release()->置null流程虽然意图是清理旧资源,但和后续的创建逻辑配合不当,容易触发MediaPlayer的非法状态操作。

修复方案1:规范MediaPlayer的生命周期管理

如果坚持用MediaPlayer,调整代码如下:

首先,成员变量只声明不提前初始化:

private MediaPlayer mSound;

然后修改点击事件逻辑:

button.setOnClickListener(new Button.OnClickListener() {
    @Override
    public void onClick(View view) {
        // 先清理旧的MediaPlayer资源
        if (mSound != null) {
            if (mSound.isPlaying()) {
                mSound.stop(); // 停止播放
            }
            mSound.release(); // 释放资源
            mSound = null;
        }
        
        // 创建新的MediaPlayer并播放
        mSound = MediaPlayer.create(getApplicationContext(), R.raw.button);
        mSound.start();
        
        // 播放完成后自动释放资源,避免内存泄漏
        mSound.setOnCompletionListener(mp -> {
            mp.release();
            mSound = null;
        });
    }
});

为什么这样改?

  • 去掉了OnCreate里的多余初始化,MediaPlayer.create()会自动完成音频文件的加载和初始化,不需要手动new。
  • 每次播放前确保旧的MediaPlayer被彻底释放,避免资源占用和状态冲突。
  • 添加OnCompletionListener,播放结束后自动清理资源,防止内存泄漏。

修复方案2:用SoundPool替代MediaPlayer(更适合短音效)

按钮点击这类短音效,用SoundPool比MediaPlayer更高效——它专门为频繁触发的短音频设计,不需要每次创建/释放对象,也不会出现状态错误:

private SoundPool soundPool;
private int buttonSoundId;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.your_layout);
    
    // 初始化SoundPool(适配Android版本)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        AudioAttributes audioAttributes = new AudioAttributes.Builder()
                .setUsage(AudioAttributes.USAGE_GAME)
                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                .build();
        soundPool = new SoundPool.Builder()
                .setMaxStreams(1) // 同时播放的最大音效数
                .setAudioAttributes(audioAttributes)
                .build();
    } else {
        // 兼容旧版本
        soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
    }
    
    // 加载音效文件(R.raw.button是你的音效资源)
    buttonSoundId = soundPool.load(this, R.raw.button, 1);
    
    // 设置按钮点击事件
    button.setOnClickListener(v -> {
        // 播放音效:参数分别是音效ID、左音量、右音量、优先级、循环次数、播放速率
        soundPool.play(buttonSoundId, 1.0f, 1.0f, 1, 0, 1.0f);
    });
}

@Override
protected void onDestroy() {
    super.onDestroy();
    // 页面销毁时释放SoundPool资源
    if (soundPool != null) {
        soundPool.release();
        soundPool = null;
    }
}

优势:

  • 音效提前加载到内存,点击时直接播放,响应更快。
  • 避免了MediaPlayer频繁创建/释放带来的状态问题和性能损耗。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:05:44