Kotlin中MediaPlayer无法循环播放Raw目录MP3资源求助
MediaPlayer音频无法循环播放问题解决
问题核心分析
你的代码存在两个关键问题,导致音频无法循环、监听器不触发:
- 监听器绑定时机错误:初始化时
mediaPlayer为null,使用?.安全调用的监听器设置代码会被直接跳过。后续创建MediaPlayer实例后,未为其绑定监听器,所以播放完成或出错时不会触发回调。 - 局部变量生命周期问题:
mediaPlayer是onCreate内的局部变量,onCreate执行完成后可能被垃圾回收,导致播放中断或状态异常。
修正后的代码
class MainActivity : AppCompatActivity() { private var mediaPlayer: MediaPlayer? = null // 提升为成员变量,避免过早被GC回收 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 初始化视图组件 val textView = findViewById<TextView>(R.id.txtSceneDescription).apply { movementMethod = ScrollingMovementMethod() text = "Run 29" } val txtPlayerCmd = findViewById<TextView>(R.id.textInputEditText) // 获取音频资源ID val soundId = resources.getIdentifier("ocean_waves", "raw", packageName) // 初始化MediaPlayer并配置播放逻辑 if (mediaPlayer == null) { Toast.makeText(this, "Media player is null, creating new instance", Toast.LENGTH_SHORT).show() mediaPlayer = MediaPlayer.create(this, soundId).apply { isLooping = true // 启用内置循环播放 // 绑定播放完成监听器 setOnCompletionListener { player -> Toast.makeText(this@MainActivity, "Playback Completed", Toast.LENGTH_SHORT).show() // 内置循环失效时,手动重置播放 if (!player.isLooping) { player.seekTo(0) player.start() } } // 绑定错误监听器 setOnErrorListener { _, errorCode, extraInfo -> Toast.makeText(this@MainActivity, "Playback Error: $errorCode, $extraInfo", Toast.LENGTH_SHORT).show() true // 标记错误已处理 } start() // 启动播放 } } else { Toast.makeText(this, "Media Player exists, starting playback", Toast.LENGTH_SHORT).show() mediaPlayer?.start() } } // Activity销毁时释放MediaPlayer资源,避免内存泄漏 override fun onDestroy() { super.onDestroy() mediaPlayer?.apply { stop() release() } mediaPlayer = null } }
关键修改说明
- 成员变量声明:把
mediaPlayer从局部变量改为Activity成员变量,避免被提前回收,保证播放状态稳定。 - 监听器正确绑定:创建MediaPlayer实例后,直接通过
apply函数为实例设置监听器,确保回调逻辑绑定到实际播放对象。 - 资源释放:添加
onDestroy方法释放MediaPlayer资源,这是Android媒体播放的标准最佳实践,防止内存泄漏。 - 双重保障循环:既启用了MediaPlayer内置的
isLooping,又在完成监听器中增加手动重启逻辑,避免内置循环失效的情况。
内容的提问来源于stack exchange,提问作者waverider57
相关产品推荐
相关产品推荐

