使用MediaPlayer时出现E/ExtMediaPlayer-JNI错误的解决方法咨询
解决MediaPlayer启动时出现
env->IsInstanceOf fails错误的方案 这个错误通常和MediaPlayer的资源管理、系统媒体框架(尤其是高通的QCMediaPlayer)的兼容性有关——虽然你的播放功能正常,但这些底层警告可能会埋下资源泄漏或后续异常的隐患,我给你几个可行的解决思路:
1. 严格管理MediaPlayer实例的生命周期
你一次性创建了两个MediaPlayer实例,但没看到对应的释放逻辑,这很容易导致系统资源占用异常,触发底层检查警告。一定要在页面销毁或不再需要这些实例时,彻底释放资源:
@Override protected void onDestroy() { super.onDestroy(); // 释放player1 if (player1 != null) { if (player1.isPlaying()) { player1.stop(); } player1.release(); player1 = null; } // 释放player2 if (player2 != null) { if (player2.isPlaying()) { player2.stop(); } player2.release(); player2 = null; } }
2. 按需初始化MediaPlayer,避免提前创建实例
不要在View初始化阶段就创建MediaPlayer实例,而是等到需要播放的时候再初始化,播放完成后立即释放,减少系统资源占用,避免和系统媒体服务的初始化冲突:
public void PlaySound(int soundResId) { // 每次播放时创建新的实例 MediaPlayer mediaPlayer = MediaPlayer.create(view.getContext(), soundResId); if (mediaPlayer != null) { mediaPlayer.start(); // 播放完成后自动释放资源 mediaPlayer.setOnCompletionListener(mediaPlayer1 -> { mediaPlayer1.release(); }); // 监听错误,避免异常扩散 mediaPlayer.setOnErrorListener((mp, what, extra) -> { mp.release(); return true; }); } }
调用时直接传资源ID即可:PlaySound(R.raw.song1)
3. 检查MP3文件的编码兼容性
虽然播放正常,但有些非标准的MP3编码格式可能会触发高通QCMediaPlayer的底层警告。你可以尝试将MP3文件转换为标准格式(比如比特率128kbps、采样率44.1kHz),替换到raw目录后再测试。
4. 使用异步初始化方式替代同步创建
MediaPlayer.create()是同步初始化,有时候会因为线程问题触发底层检查失败。改用异步prepare的方式会更稳定:
public void PlaySound(int soundResId) { MediaPlayer mediaPlayer = new MediaPlayer(); try { AssetFileDescriptor afd = view.getContext().getResources().openRawResourceFd(soundResId); mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); afd.close(); // 异步准备,避免阻塞主线程 mediaPlayer.prepareAsync(); mediaPlayer.setOnPreparedListener(mp -> mp.start()); // 播放完成或出错时及时释放资源 mediaPlayer.setOnCompletionListener(mp -> mp.release()); mediaPlayer.setOnErrorListener((mp, what, extra) -> { mp.release(); return true; }); } catch (IOException e) { e.printStackTrace(); mediaPlayer.release(); } }
优先尝试前两个方案,这是最常见的解决思路,大部分情况下都能消除这个警告。
内容的提问来源于stack exchange,提问作者Mathan Chinna




