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

如何让SplashScreen等待MainActivity的ViewModel满足指定条件?

如何让Jetpack Compose启动页等待AppViewModel的状态就绪?

我遇到了这样的问题:在Jetpack Compose项目中,想要让启动页等待AppViewModel里的状态变量变为true,但初始代码存在逻辑矛盾:

初始代码如下:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {

        installSplashScreen().setKeepOnScreenCondition {appViewModel.isReady}
        
        super.onCreate(savedInstanceState)

        setContent {

            val appViewModel: AppViewModel = viewModel(factory = AppViewModel.factory)

            val uiState by appViewModel.uiStateFlow.collectAsState()
            // 其他Composable代码
        }
    }
}

问题点很明确:调用appViewModel.isReady时,appViewModel还未定义——它是在setContent的Composable函数内部声明的。如果尝试在setContent之前用Composable的viewModel()方法声明,会报错“@Composable invocations can only happen within the context of @Composable function”,同时根据官方文档,installSplashScreen()必须在super.onCreate()之前调用,这就陷入了两难。

解决方案

最终我找到的可行写法是使用Activity级别的viewModels()扩展方法,而非Composable上下文里的viewModel():

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        val appViewModel by viewModels<AppViewModel> { AppViewModel.factory }

        installSplashScreen().setKeepOnScreenCondition { appViewModel.isLoading }

        super.onCreate(savedInstanceState)

        setContent {
            val uiState by appViewModel.uiStateFlow.collectAsState()
            // 其他Composable代码
        }
    }
}

原理说明

viewModels()是ComponentActivity的扩展方法,它可以在Activity的onCreate方法中直接获取ViewModel实例,不需要依赖Composable上下文,完美避开了之前的报错问题。这样就能在调用installSplashScreen()之前初始化ViewModel,并用它的状态(比如示例里的isLoading)来控制启动页是否保持显示,直到准备工作完成。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 07:02:45