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

Jetpack Compose中ExoPlayer生命周期切换的帧异常问题求助

修复ExoPlayer后台切前台暂停状态下视频帧跳动问题

1. 采用官方推荐的生命周期自动绑定方案

放弃手动在ON_PAUSE调用pause(),直接将ExoPlayer与页面生命周期绑定,让框架自动处理状态切换,避免手动管理的疏漏:

val exoPlayer = ExoPlayer.Builder(context)
    .setLifecycle(lifecycle) // 绑定页面生命周期
    .build()
// 初始化配置
exoPlayer.repeatMode = Player.REPEAT_MODE_ONE
exoPlayer.playWhenReady = false
exoPlayer.setMediaItem(MediaItem.fromUri(uri))
exoPlayer.prepare()
exoPlayer.play()

如果使用PlayerView承载视频,直接赋值即可自动关联生命周期:

playerView.player = exoPlayer

2. 手动处理生命周期时补充资源清理逻辑

若必须手动管控生命周期,除ON_PAUSE暂停播放外,需在ON_STOP阶段清除视频Surface资源,避免前台恢复时渲染缓存帧:

lifecycle.addObserver(object : DefaultLifecycleObserver {
    override fun onPause(owner: LifecycleOwner) {
        exoPlayer.pause()
    }

    override fun onStop(owner: LifecycleOwner) {
        exoPlayer.clearVideoSurface() // 清除关联的Surface,阻断缓存帧渲染
    }

    override fun onStart(owner: LifecycleOwner) {
        // 恢复Surface关联
        playerView.player = exoPlayer
    }
})

3. 调整渲染视图的缓存设置

如果使用TextureView作为视频载体,禁用不必要的缓存配置:

textureView.isOpaque = true
textureView.setLayerType(View.LAYER_TYPE_HARDWARE, null)

布局文件中也可直接设置:

<TextureView
    android:id="@+id/textureView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layerType="hardware"/>

4. 前台恢复时强制同步播放位置

在页面回到前台时,手动调用seekTo同步当前播放位置,强制刷新渲染帧:

override fun onResume(owner: LifecycleOwner) {
    if (!exoPlayer.isPlaying) {
        exoPlayer.seekTo(exoPlayer.currentPosition)
    }
}

内容的提问来源于stack exchange,提问作者Mustafa Tatarhan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 18:06:04