Android Jetpack Compose中ExoPlayer播放结束后重播按钮失效问题求助
Android Jetpack Compose中ExoPlayer播放结束后重播按钮失效问题求助
兄弟,我看了你的问题,大概率是Composable重组导致ExoPlayer实例被重新创建了,按钮操作的是旧实例所以没反应,具体给你拆解下:
你现在把ExoPlayer的创建代码直接写在Composable函数里,没有用remember缓存这个实例。当你调用viewModel.showNextButton()修改ViewModel状态后,会触发Composable重组——这时候你的代码会重新执行一遍,生成一个全新的ExoPlayer实例,但你的重播按钮绑定的还是重组前的旧实例!旧实例可能已经和PlayerView解绑或者处于不可用状态,自然点击没效果。
另外你的ViewModel状态设计也有问题:TutorialUiState里嵌套了MutableState<Boolean>,这种结构很容易导致状态更新时触发不必要的重组,甚至出现状态更新异常。
解决方案
1. 用remember缓存ExoPlayer实例
确保整个Composable生命周期内只有一个ExoPlayer实例,避免重组时重复创建:
val context = LocalContext.current val packageName = context.packageName // 用remember锁定ExoPlayer实例,仅在首次Compose时创建 val exoPlayer = remember { ExoPlayer.Builder(context) .build() .also { player -> val mediaItem = MediaItem.Builder() .setUri(Uri.parse("android.resource://$packageName/${R.raw.xxxxxx}")) .build() player.setMediaItem(mediaItem) player.playWhenReady = true player.videoScalingMode = C.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING player.addListener(playerEventListener) player.prepare() } } DisposableEffect(Unit) { onDispose { exoPlayer.release() } }
2. 优化ViewModel的状态结构
把嵌套的可变状态改成扁平化结构,避免状态更新异常:
// 去掉嵌套的MutableState,用普通属性存储状态 data class TutorialUiState( val showNextButton: Boolean = false ) class TutorialViewModel(application: HDiagsApplication) : AndroidViewModel(application) { private val _uiState = MutableStateFlow(TutorialUiState()) val uiState = _uiState.asStateFlow() fun showNextButton() { // 通过更新StateFlow的value来修改状态,符合Compose状态规范 _uiState.update { it.copy(showNextButton = true) } } }
3. 确保按钮关联正确的ExoPlayer实例
因为用remember缓存了ExoPlayer,重组时按钮会自动绑定同一个实例,点击seekTo(0)和play()就能正常触发重播了。
备注:内容来源于stack exchange,提问作者Luke Dawe
相关产品推荐
相关产品推荐

