Android重复播放音频时出现E/MediaPlayer: error (1, -19)问题求助
解决MediaPlayer错误(1,-19):按钮点击音效播放问题
这个E/MediaPlayer: error (1, -19)错误本质是MediaPlayer状态管理混乱导致的,你的代码里有几个关键问题:
- 你在
OnCreate里提前初始化了mSound = new MediaPlayer(),但点击事件里又重复new MediaPlayer(),还混合了MediaPlayer.create()(这个方法本身会返回一个已经初始化好的MediaPlayer实例,不需要额外new),导致对象状态冲突。 - 每次点击时的
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
相关产品推荐
相关产品推荐

