You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose中应用退至后台时如何停止MediaPlayer?

解决应用退至后台时停止MediaPlayer的问题

问题根源

你当前的DisposableEffect(Unit)只会在Composable被销毁时触发onDispose(比如屏幕旋转引发的重组),但应用退至后台时Composable并未销毁,所以MediaPlayer不会停止。而你写的ViewModel生命周期观察者没生效,核心原因是没有把观察者绑定到Activity/Fragment的Lifecycle实例上。

方法一:用LifecycleEffect监听应用前后台状态

在Compose中可以通过LifecycleEffect直接监听生命周期事件,当应用进入后台状态时暂停/停止播放:

val current = LocalContext.current
val player1: MediaPlayer = remember { MediaPlayer.create(current, R.raw.music1) }
val lifecycle = LocalLifecycleOwner.current.lifecycle

LifecycleEffect(lifecycle) {
    val observer = LifecycleEventObserver { _, event ->
        when (event) {
            Lifecycle.Event.ON_RESUME -> {
                if (!player1.isPlaying) {
                    player1.start()
                }
            }
            Lifecycle.Event.ON_PAUSE -> {
                if (player1.isPlaying) {
                    player1.pause()
                }
            }
            Lifecycle.Event.ON_DESTROY -> {
                player1.release()
            }
        }
    }
    lifecycle.addObserver(observer)
    onDispose {
        lifecycle.removeObserver(observer)
        player1.release()
    }
}

// 初始化播放逻辑
DisposableEffect(Unit) {
    player1.isLooping = true
    player1.start()
    onDispose {
        player1.stop()
        player1.release()
    }
}

方法二:修复ViewModel的生命周期绑定

如果想用ViewModel统一管理播放器,需要在宿主组件(Activity/Fragment)中完成生命周期绑定:

  1. 完善ViewModel逻辑:
class ExampleClass(application: Application) : AndroidViewModel(application) {
    private var player: MediaPlayer? = null

    fun initPlayer() {
        if (player == null) {
            player = MediaPlayer.create(getApplication(), R.raw.music1)
            player?.isLooping = true
        }
    }

    fun startPlaying() {
        player?.start()
    }

    fun pausePlaying() {
        player?.pause()
    }

    fun releasePlayer() {
        player?.stop()
        player?.release()
        player = null
    }
}
  1. 在Activity中绑定生命周期观察者:
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val viewModel = ViewModelProvider(this)[ExampleClass::class.java]
        
        lifecycle.addObserver(object : DefaultLifecycleObserver {
            override fun onResume(owner: LifecycleOwner) {
                viewModel.initPlayer()
                viewModel.startPlaying()
            }

            override fun onPause(owner: LifecycleOwner) {
                viewModel.pausePlaying()
            }

            override fun onDestroy(owner: LifecycleOwner) {
                viewModel.releasePlayer()
            }
        })

        setContent {
            // 你的Compose页面内容
        }
    }
}

关键注意点

  • 务必在组件销毁时调用MediaPlayer.release(),避免内存泄漏和资源占用。
  • 应用退至后台时,系统可能会回收资源,建议在ON_PAUSE事件中暂停播放,ON_DESTROY事件中彻底释放播放器。

内容的提问来源于stack exchange,提问作者Mr.P.Panther

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 00:35:20