Android端MediaPlayer切换歌曲时崩溃问题求助
问题原因
你遇到的IllegalStateException核心问题是MediaPlayer引用管理错误:
- 第一次切歌时,你释放了全局的MediaPlayer实例,但紧接着创建的是局部变量
mediaPlayer,全局引用仍指向已释放的无效实例。 - 第二次点击时,调用
stop()/reset()/release()时,全局实例已经处于被释放的不可用状态,直接触发非法状态异常。 - 注释掉这些方法后多歌同时播放,是因为每次点击都创建了新的MediaPlayer实例,旧实例未被释放,一直在后台运行。
修复代码
修改切歌逻辑,复用全局MediaPlayer引用,正确管理其生命周期:
// 全局变量改为可空var,方便后续重新赋值 private var mediaPlayer: MediaPlayer? = null // 启动初始化(注意:MediaPlayer.create已完成prepare,无需手动调用) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // ...其他初始化代码 mediaPlayer = MediaPlayer.create(this, R.raw.cant_let_go) mediaPlayer?.start() } // 切歌点击事件处理 adapter = RVDiffAdapter(object : RVDiffAdapter.OnAdapterListener { override fun onCLick(name: String, rawId:Int) { Toast.makeText(applicationContext, name, Toast.LENGTH_SHORT).show() Log.d("XXX", "name $name") Log.d("XXX", "rawId $rawId") // 安全处理旧实例:停止播放并释放资源 mediaPlayer?.let { mp -> if (mp.isPlaying) mp.stop() mp.release() } // 重新初始化全局实例并播放 mediaPlayer = MediaPlayer.create(applicationContext, rawId) mediaPlayer?.start() } })
额外注意事项
- 避免重复prepare:
MediaPlayer.create()内部已经完成了prepare()操作,手动调用会触发另一个IllegalStateException。 - Activity生命周期收尾:在
onDestroy()中释放资源,防止内存泄漏:
override fun onDestroy() { super.onDestroy() mediaPlayer?.let { if (it.isPlaying) it.stop() it.release() mediaPlayer = null } }
- 空安全检查:始终用
?.或let处理MediaPlayer的可空引用,避免空指针异常。
内容的提问来源于stack exchange,提问作者user19862929
相关产品推荐
相关产品推荐

