Android 12+双启动页问题求助:已实现SplashScreen API仍被检测
修复Android 12+双启动屏问题方案
核心问题分析
Play商店检测到双启动屏,通常是因为启动屏状态更新不及时、旧启动屏配置残留,或者页面内容加载延迟导致系统 fallback 到默认启动屏。结合你的代码,主要问题集中在启动屏保持条件的状态同步和页面内容占位缺失上。
修正后的代码
MainActivity 代码调整
@AndroidEntryPoint class MainActivity : ComponentActivity() { private val viewModel by viewModels<MainLayoutViewModel>() override fun onCreate(savedInstanceState: Bundle?) { // 必须在 super.onCreate 之前调用,这是官方要求的正确时机 val splashScreen = installSplashScreen() super.onCreate(savedInstanceState) // 用 AtomicBoolean 确保线程安全的状态更新,避免闭包捕获值不同步 val keepSplashScreenOn = AtomicBoolean(viewModel.isLoading.value) lifecycleScope.launch { // 切换到 RESUMED 状态收集数据,确保Activity可见时才同步状态 lifecycle.repeatOnLifecycle(Lifecycle.State.RESUMED) { viewModel.isLoading.collect { loading -> keepSplashScreenOn.set(loading) } } } splashScreen.setKeepOnScreenCondition { keepSplashScreenOn.get() } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannelManager.apply { createNotificationChannelFCM(applicationContext) createNotificationChannelTest(applicationContext) } } WindowCompat.setDecorFitsSystemWindows(window, false) setContent { SmartcubeAppTheme { val startDestination by viewModel.startDestination.collectAsStateWithLifecycle() Box(Modifier.safeDrawingPadding()) { // 即使startDestination未就绪,也要显示占位布局,避免页面空白触发系统默认启动屏 startDestination?.let { MainLayout(initialScreen = it) } ?: run { Box(Modifier.fillMaxSize()) } } } } } }
MainLayoutViewModel 代码调整
@HiltViewModel class MainLayoutViewModel @Inject constructor( private val tokenAppRepositoryImpl: ITokenAppRepository ) : ViewModel() { private val _startDestination = MutableStateFlow<String?>(null) val startDestination: StateFlow<String?> = _startDestination val isLoading: MutableStateFlow<Boolean> = MutableStateFlow(true) init { getFlowToken() } private fun getFlowToken() { viewModelScope.launch { // 用 first() 获取单次结果,避免不必要的持续监听导致内存泄漏 tokenAppRepositoryImpl.getFlowAccessToken() .first { it !is SessionState.Loading } .let { result -> when (result) { is SessionState.Empty -> { _startDestination.value = Screen.Login.screenRoute } is SessionState.Exist -> { _startDestination.value = Screen.Dashboard.screenRoute } else -> Unit } isLoading.value = false } } } }
额外配置检查
- 主题配置:确保MainActivity的启动主题继承自
Theme.SplashScreen,并指定postSplashScreenTheme:
<style name="Theme.App.SplashScreen" parent="Theme.SplashScreen"> <item name="windowSplashScreenBackground">@color/splash_bg</item> <item name="windowSplashScreenAnimatedIcon">@drawable/ic_splash_icon</item> <item name="postSplashScreenTheme">@style/Theme.SmartcubeApp</item> </style>
在Manifest中给MainActivity设置该主题:
<activity android:name=".MainActivity" android:theme="@style/Theme.App.SplashScreen"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
- 移除旧配置:删除项目中旧的SplashActivity、基于
windowBackground的启动屏主题等残留配置。
内容的提问来源于stack exchange,提问作者Iqbal Maulana
相关产品推荐
相关产品推荐

