Android MediaPlayer调用setDataSource时抛出IllegalStateException问题求助
解决MediaPlayer调用setDataSource时抛出的IllegalStateException异常
嘿,我来帮你搞定这个头疼的问题!你遇到的java.lang.IllegalStateException根源在于MediaPlayer的状态管理错误——当你调用stop()方法后,MediaPlayer会进入Stopped状态,这个状态下直接调用setDataSource()是完全不被允许的,必须先把MediaPlayer重置到Idle状态才行。
问题出在哪?
看你的stopPlay()方法:
private fun stopPlay() { mediaPlayer!!.pause() mediaPlayer!!.stop() }
调用stop()之后,MediaPlayer就停留在了Stopped状态,这时候你在playSong()里直接调用setDataSource(),就触发了状态异常,因为Stopped状态下只能调用reset()或者release(),不能直接设置数据源。
修复方案
1. 修正stopPlay()方法,添加重置操作
我们需要在停止播放后,把MediaPlayer重置到Idle状态,这样后续才能重新设置数据源:
private fun stopPlay() { // 先判断是否在播放,再暂停 if (mediaPlayer?.isPlaying == true) { mediaPlayer?.pause() } mediaPlayer?.stop() mediaPlayer?.reset() // 关键步骤:重置到Idle状态,允许后续设置数据源 }
2. 优化playSong()方法,简化逻辑并避免重复代码
把重复的监听器设置、状态判断逻辑抽离,同时做好空安全处理:
private fun playSong(songPath: String) { if (mediaPlayer == null) { mediaPlayer = MediaPlayer().apply { setOnPreparedListener(this@YourActivity) // 替换成你的类名 setOnCompletionListener(this@YourActivity) } } else { // 如果MediaPlayer不在Idle状态,先处理状态 when { mediaPlayer?.isPlaying == true -> stopPlay() mediaPlayer?.isPlaying == false -> mediaPlayer?.reset() } } // 此时MediaPlayer处于Idle状态,可以安全设置数据源 mediaPlayer?.setDataSource(songPath) mediaPlayer?.prepareAsync() }
补充说明
- MediaPlayer有严格的状态机,每个方法都只能在特定状态下调用,一定要遵循状态流转规则。
- 尽量用
?.替代!!做空安全判断,避免潜在的空指针异常。 - 当你不再需要MediaPlayer时,记得调用
release()释放资源,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Muhammad Sajid
相关产品推荐
相关产品推荐

