You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用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

火山引擎 最新活动