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

Jetpack Compose使用Navigation时启动后出现空白屏问题求助

问题:Compose导航导致闪屏后出现空白屏

我在Composable间实现简单导航时,遇到MainActivity启动性能问题。使用SplashScreen API实现闪屏,代码如下:

installSplashScreen()
super.onCreate(savedInstanceState)

setContent {
    MyTheme {
        Navigation()
    }
}

闪屏结束后、第一个Composable显示前会出现一秒空白屏。移除Navigation直接使用ComposableScreen时,无空白屏问题。我的Navigation代码如下:

@Composable
fun Navigation(
    modifier: Modifier = Modifier,
    navController: NavHostController = rememberNavController(),
    startDestination: String = ScreenRoutes.Ls.route,
) {
    NavHost(
        modifier = modifier,
        navController = navController,
        startDestination = startDestination
    ) {
        composable(route = ScreenRoutes.Ls.route) {
            Ls() { destination ->
                when (destination) {
                    ScreenRoutes.Ms-> {
                        navController.navigate(destination.route) {
                            popUpTo(0)
                        }
                    }
                    ScreenRoutes.Fp-> {
                        navController.navigate(destination.route)
                    }
                    ScreenRoutes.Ls-> {}
                    ScreenRoutes.Sc-> {
                        navController.navigate(destination.route)
                    }
                    ScreenRoutes.Up -> navController.navigateUp()
                }
            }
        }

        composable(route = ScreenRoutes.Sc.route) {
            Sc() { destination ->
                if (destination == ScreenRoutes.Up && navController.previousBackStackEntry != null) {
                    navController.navigateUp()
                } else {
                    navController.navigate(destination.route) {
                        popUpTo(0)
                    }
                }

            }
        }

        composable(route = ScreenRoutes.Ms.route) {
            Ms() {

            }
        }

        composable(route = ScreenRoutes.fg.route) {
            ForgotPassword() { destination ->
                if (destination == ScreenRoutes.Up && navController.previousBackStackEntry != null) {
                    navController.navigateUp()
                } else {
                    navController.navigate(destination.route)
                }

            }
        }
    }
}

已尝试开启minify和proguard的release版本,空白屏问题略有改善但仍存在。需要可行的优化方案,或让闪屏直到组合完成后再消失的方法。


优化方案

1. 控制闪屏直到Compose初始化完成

利用SplashScreen API的setKeepOnScreenCondition方法,让闪屏保持显示直到Compose完成首次组合和绘制:

override fun onCreate(savedInstanceState: Bundle?) {
    val splashScreen = installSplashScreen()
    super.onCreate(savedInstanceState)

    var isComposeReady by mutableStateOf(false)

    setContent {
        MyTheme {
            // 首次组合完成后标记就绪
            LaunchedEffect(Unit) {
                // 可在此添加必要的异步初始化操作(如预加载数据)
                isComposeReady = true
            }

            Navigation()
        }
    }

    // 闪屏保持显示的条件:Compose未就绪
    splashScreen.setKeepOnScreenCondition {
        !isComposeReady
    }
}

2. 优化Navigation启动性能

  • 轻量化启动页面Ls():检查Ls()是否在初始组合时执行了同步耗时操作(如复杂计算、同步IO),将这些操作移到LaunchedEffect中异步执行,避免阻塞UI线程。
  • 避免预加载非启动页面:NavHost默认会提前处理部分页面的状态,可通过简化页面间的过渡动画(如暂时禁用enterTransition)减少启动时的计算开销。
  • 优化主题初始化:如果MyTheme包含自定义字体加载、动态主题计算等逻辑,将这些操作异步化,比如用remember配合LaunchedEffect加载字体,避免阻塞主题初始化。

3. 预加载关键资源

在闪屏阶段提前初始化Compose所需的关键资源,减少启动时的等待:

override fun onCreate(savedInstanceState: Bundle?) {
    val splashScreen = installSplashScreen()
    super.onCreate(savedInstanceState)

    var isReady by mutableStateOf(false)
    // 提前初始化NavController,避免在Compose中重复创建
    val navController = rememberNavController()

    setContent {
        MyTheme {
            // 预加载自定义字体等资源
            val customFont = remember {
                FontFamily(Font(R.font.app_font, FontWeight.Normal))
            }

            LaunchedEffect(customFont) {
                // 等待资源加载完成后标记就绪
                isReady = true
            }

            Navigation(navController = navController)
        }
    }

    splashScreen.setKeepOnScreenCondition {
        !isReady
    }
}

4. 分析并优化UI绘制耗时

使用Android Studio的Compose Profiler或Layout Inspector分析启动过程中的UI绘制耗时,定位Ls()或Navigation中导致延迟的布局、Modifier或状态计算逻辑,针对性简化优化。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 16:20:21