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

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>

问题原因及修复方案

核心原因

  1. 主题初始化顺序错误:部分Android设备上,super.onCreate(null)执行后会先渲染系统默认的黑色窗口背景,之后才加载RNBootSplash的自定义主题,导致黑屏闪现。
  2. BootTheme配置不完整:未明确设置窗口背景、状态栏/导航栏颜色,系统 fallback 到默认黑色。
  3. 资源加载延迟:部分设备上闪屏图片资源加载慢,背景色先显示为默认黑色,图片加载完成后才覆盖。

修复步骤

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_

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 23:42:34