React Native安卓应用启动闪屏前出现黑屏问题求助
React Native启动闪屏前短暂黑屏问题排查与修复(Android)
问题描述
在React Native应用中使用"react-native-bootsplash": "^6.2.2"实现启动闪屏时,部分Android设备上会先短暂显示带闪屏图片的黑色背景,随后才切换到代码中定义的白色背景+闪屏图片的正常状态。已尝试清除Metro和Gradle缓存,问题仍未解决。
闪屏截图


平台:Android
环境信息
System: OS: Windows 11 10.0.22631 CPU: "(4) x64 AMD Ryzen 3 4300U with Radeon Graphics " Memory: 9.18 GB / 19.37 GB Binaries: Node: version: 20.14.0 path: C:\Program Files\nodejs\node.EXE Yarn: Not Found npm: version: 10.7.0 path: C:\Program Files\nodejs\npm.CMD Watchman: Not Found SDKs: Android SDK: API Levels: - "29" - "30" - "31" - "32" - "33" - "34" - "35" Build Tools: - 30.0.2 - 30.0.3 - 33.0.0 - 33.0.1 - 34.0.0 - 35.0.0 System Images: - android-30 | Google Play Intel x86 Atom - android-33 | Google APIs Intel x86_64 Atom - android-35 | Google APIs Intel x86_64 Atom Android NDK: Not Found Windows SDK: Not Found IDEs: Android Studio: AI-232.10300.40.2321.11668458 Visual Studio: Not Found Languages: Java: javac 17 Ruby: Not Found npmPackages: "@react-native-community/cli": Not Found react: installed: 18.2.0 wanted: 18.2.0 react-native: installed: 0.74.6 Android: hermesEnabled: true newArchEnabled: false iOS: hermesEnabled: Not found newArchEnabled: Not found
相关代码文件
1. App.tsx
import React, {useEffect} from 'react'; import type {PropsWithChildren} from 'react'; import { SafeAreaView, ScrollView, StatusBar, StyleSheet, Text, useColorScheme, View, } from 'react-native'; import { Colors, DebugInstructions, Header, LearnMoreLinks, ReloadInstructions, } from 'react-native/Libraries/NewAppScreen'; import BootSplash from 'react-native-bootsplash'; type SectionProps = PropsWithChildren<{ title: string; }>; function Section({children, title}: SectionProps): React.JSX.Element { const isDarkMode = useColorScheme() === 'dark'; return ( <View style={styles.sectionContainer}> <Text style={[ styles.sectionTitle, { color: isDarkMode ? Colors.white : Colors.black, }, ]}> {title} </Text> <Text style={[ styles.sectionDescription, { color: isDarkMode ? Colors.light : Colors.dark, }, ]}> {children} </Text> </View> ); } function App(): React.JSX.Element { useEffect(() => { const init = async () => { // …do multiple sync or async tasks }; init().finally(async () => { await BootSplash.hide({fade: true}); console.log('BootSplash has been hidden successfully'); }); }, []); const isDarkMode = useColorScheme() === 'dark'; const backgroundStyle = { backgroundColor: isDarkMode ? Colors.darker : Colors.lighter, }; return ( <SafeAreaView style={backgroundStyle}> <StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} backgroundColor={backgroundStyle.backgroundColor} /> <ScrollView contentInsetAdjustmentBehavior="automatic" style={backgroundStyle}> <Header /> <View style={{ backgroundColor: isDarkMode ? Colors.black : Colors.white, }}> <Section title="Step One"> Edit <Text style={styles.highlight}>App.tsx</Text> to change this screen and then come back to see your edits. </Section> <Section title="See Your Changes"> <ReloadInstructions /> </Section> <Section title="Debug"> <DebugInstructions /> </Section> <Section title="Learn More"> Read the docs to discover what to do next: </Section> <LearnMoreLinks /> </View> </ScrollView> </SafeAreaView> ); } const styles = StyleSheet.create({ sectionContainer: { marginTop: 32, paddingHorizontal: 24, }, sectionTitle: { fontSize: 24, fontWeight: '600', }, sectionDescription: { marginTop: 8, fontSize: 18, fontWeight: '400', }, highlight: { fontWeight: '700', }, }); export default App;
2. AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <uses-permission android:name="android.permission.INTERNET" /> <application android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="false" android:theme="@style/AppTheme"> <activity android:name=".MainActivity" android:label="@string/app_name" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode" android:launchMode="singleTask" android:windowSoftInputMode="adjustResize" android:exported="true" android:theme="@style/BootTheme"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
3. MainActivity.kt
package com.rnbootsplash import com.facebook.react.ReactActivity import com.facebook.react.ReactActivityDelegate import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled import com.facebook.react.defaults.DefaultReactActivityDelegate import android.os.Bundle import com.zoontek.rnbootsplash.RNBootSplash class MainActivity : ReactActivity() { override fun onCreate(savedInstanceState: Bundle?) { RNBootSplash.init(this, R.style.BootTheme) // ⬅️ initialize the splash screen super.onCreate(null) // or super.onCreate(null) with react-native-screens } /** * Returns the name of the main component registered from JavaScript. This is used to schedule * rendering of the component. */ override fun getMainComponentName(): String = "RnBootsplash" /** * Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate] * which allows you to enable New Architecture with a single boolean flags [fabricEnabled] */ override fun createReactActivityDelegate(): ReactActivityDelegate = DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled) }
4. colors.xml
<resources> <color name="bootsplash_background">#ffffff</color> </resources>
问题原因及修复方案
核心原因
- 主题初始化顺序错误:部分Android设备上,
super.onCreate(null)执行后会先渲染系统默认的黑色窗口背景,之后才加载RNBootSplash的自定义主题,导致黑屏闪现。 - BootTheme配置不完整:未明确设置窗口背景、状态栏/导航栏颜色,系统 fallback 到默认黑色。
- 资源加载延迟:部分设备上闪屏图片资源加载慢,背景色先显示为默认黑色,图片加载完成后才覆盖。
修复步骤
1. 调整MainActivity初始化顺序(关键)
将super.onCreate移至RNBootSplash.init之前,让系统先完成Activity初始化,再绑定闪屏主题:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(null) // 先执行父类初始化 RNBootSplash.init(this, R.style.BootTheme) // 再初始化闪屏 }
2. 完善BootTheme配置
检查res/values/styles.xml中的BootTheme定义,确保继承正确基础主题并设置完整的窗口属性:
<style name="BootTheme" parent="Theme.MaterialComponents.NoActionBar"> <!-- 绑定react-native-bootsplash生成的闪屏Drawable --> <item name="android:windowBackground">@drawable/bootsplash</item> <!-- 同步状态栏/导航栏颜色与闪屏背景 --> <item name="android:statusBarColor">@color/bootsplash_background</item> <item name="android:navigationBarColor">@color/bootsplash_background</item> <!-- 隐藏ActionBar --> <item name="windowActionBar">false</item> <item name="windowNoTitle">true</item> </style>
3. 全局临时使用BootTheme
在AndroidManifest.xml的application标签中临时设置默认主题为BootTheme,避免App启动时的主题切换闪烁:
<application ... android:theme="@style/BootTheme"> <!-- 替换原AppTheme --> <activity ... android:theme="@style/BootTheme"> ... </activity> </application>
待闪屏隐藏后,在App.tsx中切换回AppTheme:
import { Platform, StatusBar } from 'react-native'; useEffect(() => { const init = async () => { // ...你的初始化逻辑 }; init().finally(async () => { await BootSplash.hide({fade: true}); // 切换回AppTheme的状态栏颜色 if (Platform.OS === 'android') { StatusBar.setBackgroundColor("#你的AppTheme状态栏颜色"); } console.log('BootSplash has been hidden successfully'); }); }, []);
4. 彻底清理缓存并重构
执行以下命令确保缓存完全清除:
# 清除Metro缓存 npx react-native start --reset-cache # 清除Gradle缓存 cd android && ./gradlew clean && cd .. # 重新构建应用 npx react-native run-android
内容的提问来源于stack exchange,提问作者rzocky_
相关产品推荐
相关产品推荐

