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

Jetpack Compose中Android新Splash Screen卡顿问题求助

问题排查与修复方案

核心问题分析

  1. 状态无法同步:MainActivity中定义的keepSplashOpened是普通变量,仅在onCreate时取一次viewModel.state的值,后续viewModel中state的更新无法同步到该变量,导致setKeepOnScreenCondition始终认为需要保持启动页显示。
  2. 状态类设计问题:SplashState中的keepSplashOpened使用var,但搭配mutableStateOf时,数据类应保持不可变性(用val),因为mutableStateOf是通过替换整个state对象触发重组,var会破坏状态更新的可靠性。
  3. 数据流收集方式不当:SplashViewModel中对readOnBoardingUseCase()的collect会持续监听数据流,若DataStore的数据流未正确终止,可能导致不必要的资源占用,甚至间接影响启动页关闭逻辑。

具体修复步骤

1. 修正SplashState的不可变性

data class SplashState(
    val graphs: String? = null,
    val keepSplashOpened: Boolean = true // 将var改为val,保持数据类不可变
)

2. 调整SplashViewModel的状态更新逻辑

@HiltViewModel
class SplashViewModel @Inject constructor(
    private val readOnBoardingUseCase: ReadOnBoardingUseCase
) : ViewModel() {

    var state by mutableStateOf(SplashState())
        private set // 限制外部直接修改状态,通过方法更新

    init {
        viewModelScope.launch {
            // 仅读取一次DataStore中的onboarding状态,而非持续监听
            val completed = readOnBoardingUseCase().first()
            state = state.copy(
                graphs = if (completed) Graph.HOME else Graph.WELCOME,
                keepSplashOpened = false
            )
        }
    }

    // 提供外部更新启动页状态的方法
    fun updateKeepSplashOpened(keep: Boolean) {
        state = state.copy(keepSplashOpened = keep)
    }
}

3. 修复MainActivity的启动页状态监听逻辑

@AndroidEntryPoint
class MainActivity : ComponentActivity() {

    private val viewModel: SplashViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // 用StateFlow追踪启动页保持状态,确保能感知ViewModel的状态变化
        val keepSplashOpened = MutableStateFlow(viewModel.state.keepSplashOpened)

        // 生命周期绑定,监听ViewModel的state变化
        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                viewModel.state.collect { newState ->
                    keepSplashOpened.value = newState.keepSplashOpened
                }
            }
        }

        installSplashScreen().setKeepOnScreenCondition {
            // 实时获取最新的状态值
            keepSplashOpened.value
        }

        setContent {
            val window = rememberWindowSizeClass()
            KippTheme(window) {
                val currentState by viewModel.state.collectAsState()
                RootNavigationGraph(
                    graph = currentState.graphs,
                    onDataLoaded = {
                        // 若需要手动触发关闭,调用ViewModel的更新方法
                        viewModel.updateKeepSplashOpened(false)
                    }
                )
            }
        }
    }
}

额外排查点

  • 检查ReadOnBoardingUseCase的实现,确保DataStore的读取逻辑无阻塞(如是否在主线程执行耗时操作)。
  • 验证引导页点击确认按钮后,DataStore是否正确写入completed = true的状态。
  • 确保Graph.HOME和Graph.WELCOME的定义正确,避免导航图加载异常导致启动页无法关闭。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 12:07:52