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

Compose中ViewModel的init块重复执行问题求助

问题原因及解决方案

核心问题:ViewModel被重复实例化

你的ExamplesScreen组件中,使用了默认参数直接创建ViewModel:

viewModel: ExampleViewModel = ExampleViewModel(section!!)

Composable每次重组时,都会执行这个默认参数的初始化逻辑,导致每次重组都会生成一个全新的ExampleViewModel实例。新实例的init块会再次触发网络请求并更新UI状态,这直接造成了加载状态与列表状态反复切换的闪烁问题。

另外,原ViewModel中两次分开的状态更新会触发两次UI重组,也会加重闪烁现象:

// 两次独立update会触发两次状态发射
_uiState.update { it.copy(isLoading = false) }
_uiState.update { it.copy(samples = samplesList) }

修复步骤

  1. 正确获取ViewModel实例
    不要在Composable默认参数中直接实例化ViewModel,改用viewModel()函数(依赖androidx.lifecycle:lifecycle-viewmodel-compose),它会通过ViewModelProvider保证同一生命周期内仅创建一个ViewModel实例。由于你的ViewModel有构造参数,需要自定义Factory:

    // 自定义ViewModel工厂类
    class ExampleViewModelFactory(private val section: String) : ViewModelProvider.Factory {
        @Suppress("UNCHECKED_CAST")
        override fun <T : ViewModel> create(modelClass: Class<T>): T {
            if (modelClass.isAssignableFrom(ExampleViewModel::class.java)) {
                return ExampleViewModel(section) as T
            }
            throw IllegalArgumentException("未知的ViewModel类")
        }
    }
    
    // 修改Composable的ViewModel获取方式
    @Composable
    fun ExamplesScreen(
        navController: NavController,
        section: String?,
        viewModel: ExampleViewModel = viewModel(factory = ExampleViewModelFactory(section!!))
    ) {
        // ... 原有UI代码
    }
    
  2. 合并UI状态更新
    将两次状态更新合并为一次,减少不必要的UI重组:

    init {
        viewModelScope.launch(Dispatchers.IO) {
            _uiState.update { it.copy(isLoading = true) }
            val samplesList = exampleRepository.getSamplesBySection(section)
            // 一次update完成所有状态变更
            _uiState.update { 
                it.copy(
                    isLoading = false,
                    samples = samplesList.takeIf { it.isNotEmpty() } ?: emptyList(),
                    isError = samplesList.isEmpty() // 可补充错误状态处理
                )
            }
        }
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 19:22:16