Android 9系统MediaPlayer空指针异常疑难问题求助
Android 9上MediaPlayer.create返回null导致空指针的解决方案
我之前也碰到过类似的问题,Android 9(API 28)在MediaPlayer的音频加载逻辑上确实有一些兼容性调整,结合你的日志和代码来看,问题根源很明确:
问题分析
从错误日志里的这两行可以定位核心问题:
E/MediaPlayerNative: Unable to create media player
D/MediaPlayer: create failed: java.io.IOException: setDataSourceFD failed.: status=0x80000000
这说明MediaPlayer.create()方法在Android 9设备上无法成功加载你的raw目录下的音频文件,返回了null,而你的代码直接调用了media_minigun[i].setOnCompletionListener(),才触发了空指针异常。
为什么只在Android 9上出现?大概率是音频文件的编码格式兼容性问题——Android 9对某些老旧的音频编码(比如低版本MP3、非标准WAV参数)的支持比旧系统更严格,即使这些文件在旧Android版本上能正常播放,到Android 9就会加载失败。
具体解决方案
1. 先检查并转换音频文件格式
优先排查音频文件本身:
- 把
minigun.mp3和minigun2.mp3转成标准的编码格式,比如用Audacity工具转成44.1kHz采样率、128kbps比特率的MP3,或者AAC格式。 - 确保音频文件没有损坏,你可以先在电脑上播放测试,再替换到raw目录中重新编译测试。
2. 增加空指针判断,避免崩溃
不管音频加载是否成功,都要先判断MediaPlayer实例是否为null,再调用相关方法,修改你的prepare_media_minigun()方法:
static void prepare_media_minigun() { for (int i = 0; i < minigun_max_ammo; i++) { MediaPlayer tempPlayer = null; // 根据是否静音选择对应的音频 if (!minigun_silencer) { tempPlayer = MediaPlayer.create(context, R.raw.minigun); } else { tempPlayer = MediaPlayer.create(context, R.raw.minigun2); } // 关键:先判断是否为null,再执行后续操作 if (tempPlayer != null) { tempPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { mp.release(); } }); media_minigun[i] = tempPlayer; } else { // 打印错误日志,方便排查哪个音频加载失败 Log.e("MediaPlayer", "Failed to load audio for index: " + i + ", silencer: " + minigun_silencer); media_minigun[i] = null; } } minigun_player_unloaded = false; }
3. 改用手动初始化MediaPlayer的方式(备选方案)
如果MediaPlayer.create()还是不行,可以尝试手动初始化MediaPlayer,这样能更精准地捕获加载过程中的异常:
static void prepare_media_minigun() { for (int i = 0; i < minigun_max_ammo; i++) { MediaPlayer player = new MediaPlayer(); try { AssetFileDescriptor afd; // 获取音频文件的Asset描述符 if (!minigun_silencer) { afd = context.getResources().openRawResourceFd(R.raw.minigun); } else { afd = context.getResources().openRawResourceFd(R.raw.minigun2); } if (afd != null) { player.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); afd.close(); player.prepare(); // 手动调用prepare player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { mp.release(); } }); media_minigun[i] = player; } else { Log.e("MediaPlayer", "Failed to get AssetFileDescriptor for audio"); player.release(); media_minigun[i] = null; } } catch (IOException e) { e.printStackTrace(); player.release(); // 异常时记得释放资源 media_minigun[i] = null; } } minigun_player_unloaded = false; }
额外提示
- 如果你在使用过程中需要播放这些音频,也要记得先判断
media_minigun[i]是否为null,避免再次出现空指针。 - 不用的MediaPlayer实例一定要及时调用
release()释放资源,避免内存泄漏。
内容的提问来源于stack exchange,提问作者pawel22
相关产品推荐
相关产品推荐

