首页
/
行业洞察
/
正文
INDUSTRY INSIGHT · 深度
expo-splash-screen 启动屏模块演进全解析:从 CHANGELOG 读透版本变更、破坏性更新与底层实现
📅 2026/9/11 12:03:13
✍️ 爱科研究院
👁 阅读 3,247
expo-splash-screen 启动屏模块演进全解析从 CHANGELOG 读透版本变更、破坏性更新与底层实现【免费下载链接】expoAn open-source framework for making universal native apps with React. Expo runs on Android, iOS, and the web.项目地址: https://gitcode.com/GitHub_Trending/ex/expoexpo-splash-screen 是 Expo 生态中负责应用启动屏Launch Screen / Splash Screen的原生模块它让开发者能够在 React Native 视图挂载前展示系统级启动画面并通过preventAutoHideAsync/hideAsync精确控制隐藏时机。本文以 packages/expo-splash-screen/CHANGELOG.md 为时间轴骨架结合 包内 README 与 Android/iOS 原生源码、config plugin 源码系统梳理该模块从 0.2.0 到 57.0.x 的演进脉络哪些是必须关注的破坏性变更、哪些新特性值得采用、哪些 Bug 修复揭示了平台的深层坑点并给出升级与迁移建议。读完本文你将能读懂任何一版 CHANGELOG 背后的技术含义并知道如何在当前仓库中定位对应实现。一、模块定位启动屏为什么值得一个原生模块启动屏是应用启动瞬间、React Native 运行时尚未接管屏幕时用户看到的第一个画面。它不仅是品牌首印象更承担着「掩护 JS Bundle 加载、资源准备、API 预热」的窗口期职责。Expo 官方文档将其描述为 the initial screen users see when the app is launched, before it has loaded。expo-splash-screen提供两类核心能力原生级展示与隐藏控制默认情况下一旦 React Native 视图层次挂载完成原生启动屏自动隐藏也可以通过preventAutoHideAsync()阻止自动隐藏待资源就绪后再调用hideAsync()手动隐藏详见 README 的 API 章节。配置即代码通过 config plugin 在app.json中声明背景色、图片、resizeMode、暗色模式、StatusBar 等prebuild 时自动生成 iOS Storyboard 与 Android drawable 资源替代手工原生配置。从仓库结构可以清晰看到它的模块化布局packages/expo-splash-screensrc/TypeScript API 层SplashScreen.ts、SplashScreen.native.ts、SplashScreen.types.tsandroid/src/main/java/expo/modules/splashscreen/Kotlin 原生实现SplashScreenModule.kt、SplashScreenManager.ktios/Swift 原生实现SplashScreenModule.swift、SplashScreenManager.swift、SplashScreenAppDelegateSubscriber.swift、SplashScreenOptions.swiftplugin/config plugin 的 TypeScript 源码与单元测试。二、版本谱系从 0.x 到 57.x 的版本命名演进CHANGELOG 展示了清晰的版本命名演变。早期2020—2025 年中为 0.x 语义化版本0.2.0至0.30.10自 2025 年 8 月起切换为与 Expo SDK 对齐的大版本命名31.0.0、55.0.0、56.0.0、57.0.0这从版本号的跳跃规律可以推断包的大版本号直接对应 Expo SDK 版本号。版本区间发布时间关键定位0.2.0 – 0.11.02020 – 2021模块诞生期CLI 工具、SplashScreen.show原生方法、iOS LaunchScreen 支持0.12.0 – 0.19.02021 – 2023免 MainActivity 配置、dark mode、状态栏自定义、config plugin 成型0.20.0 – 0.30.102023 – 2025Expo Modules API 化、expo-router 编排迁移、tvOS、矢量 drawable、expo modules gradle plugin31.0.0 – 57.0.x2025 – 2026与 SDK 版本对齐config plugin 迁入本包类型化 plugincore-splashscreen 稳定版值得一提的细节版本号并不代表「每版都有用户可见变化」。CHANGELOG 中大量版本标注为 This version does not introduce any user-facing changes如 57.0.0 – 57.0.5 连续多个版本、56.0.1 – 56.0.6 等说明这些发版主要用于依赖同步、构建管线修复或内部维护升级时可以放心平滑过渡。三、破坏性变更Breaking Changes全梳理这是升级时最需要关注的部分按影响面分类如下。3.1 最低系统版本持续上调iOS / macOS / AndroidCHANGELOG 记录了完整的最低版本演进链0.8.02020-11iOS 改用use_frameworks!将React依赖替换为React-Core0.9.02021-01放弃 iOS 10.0 支持0.13.02021-09放弃 iOS 11.0 支持0.17.02022-10iOS deployment target 升至 13.0弃用 iOS 120.25.02023-11iOS target 升至 13.4AndroidcompileSdkVersion与targetSdkVersion升至 340.28.02024-10iOS / tvOS deployment target 升至 15.156.0.02026-05最低 iOS/tvOS 版本升至 16.4macOS 升至 13.4。Android 侧的 SDK 目标同样一路抬升0.10.0 支持 Android 11SDK 30→ 0.15.0 升至 compileSdk/targetSdk 31 且 Java 11 → 0.18.0 升至 33 → 0.25.0 升至 34 → 0.24.0 直接放弃 Android SDK 21 与 22API 23 的设备不再支持。升级提示若你的项目仍要兼容 iOS 15 及以下或老 Android 设备请锁定对应旧版本反之使用新版本前务必同步提升项目的最低系统版本配置。3.2 弃用与移除的 API0.23.02023-09删除已弃用的hide与preventAutoHide方法注意是旧版同步方法不是现在的hideAsync/preventAutoHideAsync。0.20.02023-06弃用expo/configure-splash-screen全面转向 splash screen config plugin早期由该 CLI 工具承担的自动化配置职责被 plugin 取代。0.3.02020-05expo-splash-screen-command被expo/configure-splash-screen替代功能不变。0.6.22020-09yarn expo-splash-screen命令行参数布局调整所有参数必须用--[option name]语法传入。3.3 Android 资源与属性清理0.4.02020-07SplashScreen.show()原生方法签名变更第三个参数改为Boolean标志位用于指示StatusBar是否translucent传false保持旧默认行为0.6.2Android 端将SplashScreen原生对象限定到独立的singletons子包以兼容版本化代码0.26.22024-01用com.facebook.react:react-android替换已弃用的com.facebook.react:react-native:Android 依赖0.27.02024-04移除废弃的向后兼容 Gradle 设置55.0.142026-04移除 Android 遗留属性expo_splash_screen_status_bar_translucent。3.4 新架构New Architecture相关55.0.02026-01iOS 端移除新架构兼容检查代码意味着不再需要针对 bridgeless 等模式做特判0.17.42022-11修复新架构 expo-dev-client 下FrameLayout.onMeasure()的 AndroidNullPointerException0.28.0修复preventAutoHideAsync()在 iOS bridgeless 模式下失效的问题。四、新特性New Features演进从能用到大而全4.1 原生启动屏图片的三种 resizeMode包内 README 定义了三种内置缩放模式这也是 config plugin 中resizeMode参数contain | cover | native默认contain见 plugin/src/types.ts的取值来源CONTAIN等比缩放图片完整可见iOS 对应 Storyboard 中 ImageView 的Aspect FitCOVER等比缩放并铺满屏幕可能裁切边缘iOS 对应Aspect FillNATIVE仅 Android利用 Android 启动期静态位图能力图片按原始尺寸居中展示不拉伸。CHANGELOG 中与之相关的修复有0.29.13「Correctly handleresizeModein config plugin」说明早期 plugin 对resizeMode的处理存在缺陷。Android 侧若要使用native模式需要按 DPI 提供drawable-mdpi/hdpi/xhdpi/xxhdpi/xxxhdpi多套splashscreen_image.png详见 README 的 Android 配置章节。4.2 暗色模式per-appearance支持0.12.0 起支持 iOS 13 与 Android 10 的系统外观切换0.29.142024-12iOS 端从any改为使用light与dark颜色让暗色适配更规范配置层面对应dark配置对象dark.image、dark.backgroundColorAndroid 端使用res/values-night/colors.xml与res/drawable-night/splashscreen_image.png实现。4.3 平台与 React Native 版本扩展0.22.02023-09支持 React Native 0.730.20.0支持 React Native 0.720.23.0新增 Apple tvOS 支持0.29.172024-12Android 支持以矢量 drawableVectorDrawable作为启动屏图标56.0.0暴露类型化 config plugin 函数typed config plugin开发者可获得完整的配置项类型提示。4.4 自动隐藏策略与 expo-router 编排这是模块职责演变的关键节点0.12.02021-09无需在 MainActivity 中额外配置即可展示启动屏并可在资源中自定义resizeMode/statusBarTranslucent0.25.02023-11将 splash screen 编排所需逻辑从expo-router迁移至expo-splash-screen并在应用抛出错误时自动关闭启动屏避免错误信息被遮挡0.29.22024-11将 router 使用的内部逻辑从 JS 迁移到原生减少 JS 侧开销。当前源码中保留了面向库使用者的内部接口。在 SplashScreen.types.ts 中可以看到_internal_maybeHideAsync与_internal_preventAutoHideAsync两个私有方法Android 侧 SplashScreenModule.kt 中internalMaybeHideAsync的实现逻辑是仅当用户没有主动调用preventAutoHideAsyncuserControlledAutoHideEnabled false时才执行隐藏——这正是 expo-router 判断「能否安全隐藏启动屏」的机制。五、Bug 修复历史读懂平台深处的坑CHANGELOG 的 Bug 修复条目揭示了启动屏场景下大量平台级疑难问题按平台归类如下。5.1 Android 侧典型问题SurfaceControl 崩溃56.0.0针对 API 31–33 的SurfaceControl.checkNotReleased崩溃在 Activity stop 时取消启动屏退出动画。对应实现见 SplashScreenManager.kt当 SDK 版本落在 S..TIRAMISU 区间时注册ActivityLifecycleCallbacks在onActivityStopped中通过runCatching清除退出动画监听器规避 Google Issue Tracker 242118185headless JS 空指针0.29.5无 Activity 的 headless JS 场景下引用splashScreen属性导致 NPESplashScreenManager.kt中通过if (!::splashScreen.isInitialized) return守卫处理expo-updates 集成0.21.0修复使用getDelayLoadAppHandler()时启动屏缺失的问题白屏闪烁0.27.0修复 expo-updates 搭配较长fallbackToCacheTimeout时出现的白屏闪烁TalkBack 兼容0.24.0移除SplashScreenView上的isClickable修复无障碍朗读行为异常新架构 NPE0.17.4FrameLayout.onMeasure()空指针Gradle 兼容0.14.2、0.20.0修复 Android Gradle 7 下Plugin with id maven not found以及 Gradle 8 的构建警告自动隐藏机制0.25.0移除 Android 上 The current activity is no longer available 警告。5.2 iOS 侧典型问题Storyboard 缺失崩溃55.0.0修复 storyboard 不存在时的崩溃对应 SplashScreenManager.swift 中guard Bundle.main.path(forResource:..., ofType: storyboardc) ! nil else { return }的防御逻辑Storyboard 名称解析31.0.0从 Info.plist 解析 StoryBoard 名称Swift 实现中读取UILaunchStoryboardName缺省回退到SplashScreen「No native splash screen registered」警告0.13.x、0.16.x、0.22.0、0.18.0这是一系列围绕「启动屏未注册/重复注册」的修复涉及 expo-dev-client、应用后台启动、reload 等场景重载后启动屏不显示0.16.1、0.29.19iOS reload 应用时重新展示启动屏Swift 中通过实现RCTReloadListener的didReceiveReloadCommand()重新调用showSplashScreen()view controller 查找策略0.12.0从「始终使用 keyWindow 的 rootViewController」改为「搜索包含 RCTRootView 的 view controller」Alert 遮挡问题0.12.0修复启动屏在 alert 出现时无法关闭的两个场景闪烁0.4.0修复启动屏与 React 阶段切换间的闪烁。5.3 exports 字段与 Expo Go 相关56.0.7修复exports字段在原生平台错误解析到 web stubs、导致preventAutoHideAsync变成空操作的问题0.29.12阻止在 Expo Go 中调用setOptions。对应 SplashScreen.native.ts 中isRunningInExpoGo()检查在 Expo Go 中会打印提示「To customize the splash screen, you can use development builds」并直接返回0.27.4原生模块未安装时静默 no-op保证模块在纯 Web 等场景不抛错。六、内部架构调整与依赖治理6.1 config plugin 的「回归」从expo/prebuild-config迁回本包0.20.0正式弃用expo/configure-splash-screensplash screen config plugin 成为官方配置入口0.17.0plugin 的 import 从expo/config-plugins迁移到expo/config-plugins从expo/config-types迁移到expo/config56.0.0将 splash screen config plugins 从expo/prebuild-config迁入expo-splash-screen包自身此后启动屏配置逻辑完全由本包自治。当前仓库中 plugin/src/withSplashScreen.ts 展示了 plugin 的组织方式通过createRunOncePlugin注册同时调用withAndroidSplashScreen与withIosSplashScreenAndroid 侧又细分为 drawables、images、strings、styles、MainActivity 等多个子 plugin见 plugin/src 目录并有对应的InterfaceBuilder-test.ts、withAndroidSplashStyles-test.ts、withIosSplashScreenStoryboardImage-test.ts等单元测试保障。6.2 Android 原生依赖升级55.0.14androidx.core:core-splashscreen从1.2.0-alpha02升级到稳定版1.2.0意味着 Android 侧正式切换到 Jetpack 官方启动屏库SplashScreenManager.kt中的installSplashScreen()即来自该库0.30.0Android 开始使用 expo modules gradle plugin0.26.2react-android 依赖替换。6.3 iOS 依赖与可见性收敛55.0.14iOS 端改用internal import React将公共 API 表面收敛到 internal 访问级别减少对外暴露0.9.0iOS 开始随包发布预编译二进制prebuilt binaries。七、配置项与 API 速查含源码默认值7.1 Config plugin 参数类型化 config plugin56.0.0 起的完整参数定义在 plugin/src/types.ts参数类型默认值说明backgroundColorstring#ffffff启动屏背景色55.0.14 起可选默认白色imageWidthnumber100图片显示宽度enableFullScreenImage_legacybooleanfalse全屏图片遗留过渡参数将被移除imagestring—启动屏图片路径resizeModecontain \| cover \| nativecontain图片缩放模式dark{ image?, backgroundColor? }—暗色模式配置androidPartialAndroidSplashConfig—Android 专用含 mdpi/hdpi/.../xxxhdpi 多密度图片iosPartialIOSSplashConfig—iOS 专用含tabletBackgroundColor、tabletImage7.2 运行时 API 与隐藏动画选项JS API 定义见 SplashScreen.ts 与 SplashScreen.native.tspreventAutoHideAsync()阻止自动隐藏返回Promiseboolean成功阻止返回true已阻止过返回false。README 特别强调应在全局作用域调用且不要await以免在组件内调用时启动屏已被隐藏hideAsync()手动隐藏启动屏仅对已调用过preventAutoHideAsync的会话有效hide()立即隐藏同步版本setOptions(options)配置隐藏动画在 Expo Go 中不可用。SplashScreenOptions在 SplashScreen.types.ts 中定义duration淡出动画毫秒数默认 400、fade是否使用淡出动画iOS 默认 false。值得注意的是 Android 侧 SplashScreenModule.kt 的SplashScreenOptions记录类中fade默认值为true双平台默认行为存在差异Android 实现使用AccelerateInterpolator alpha 动画淡出并在 API 31 时通过splashScreenViewProvider.remove()、API 31 时直接调用SplashScreenView.remove()完成移除。7.3 自动隐藏的双平台触发机制AndroidSplashScreenManager.kt注册ReactMarker.MarkerListener当收到ReactMarkerConstants.CONTENT_APPEARED且未调用preventAutoHideAsync时执行hide()同时通过OnPreDrawListener在 API 33 时自行实现「保持启动屏」逻辑iOSSplashScreenManager.swift监听RCTContentDidAppearNotification未阻止自动隐藏时调用hide()淡出通过UIView.transition(with:options: .transitionCrossDissolve)实现。八、迁移与升级建议8.1 从旧版 0.12.0迁移CHANGELOG 与 README 均给出明确步骤从react-native-unimodules迁移到expo-modules-core从 MainActivity 中移除旧式手动调用代码删除SplashScreen.show(...)与SplashScreenImageResizeMode相关 import保留setTheme(R.style.AppTheme)如需覆盖默认resizeMode在res/values/strings.xml中声明string nameexpo_splash_screen_resize_modecontain/string。8.2 升级到 56.x / 57.x 的检查清单系统版本门槛确认 iOS/tvOS 16.4、macOS 13.456.0.0 起配置迁移若此前使用expo/prebuild-config中的启动屏配置56.0.0 已将其迁入expo-splash-screen自身确认依赖与npx expo prebuild重新生成原生工程Expo Go 限制setOptions在 Expo Go 中不可用需要 development build 才能自定义启动屏原生依赖Android 端已切到稳定版androidx.core:core-splashscreen:1.2.0无需额外手工适配无用户可见变化的版本如 57.0.0–57.0.5可放心升级但仍建议升级后回归验证启动屏在冷启动、热重载、expo-updates 场景下的表现。8.3 关注 Unpublished 待发布变更CHANGELOG 头部 Unpublished 段已记录一项待发布修复当 config plugin 未提供图片时生成透明的 Android 启动屏 drawable——这意味着无图配置纯色启动屏在 Android 上会获得更干净的实现不会出现默认占位图。九、总结透过 CHANGELOG 可以完整还原 expo-splash-screen 六年的技术路线从裸 RN 项目中的 CLI 辅助配置expo-splash-screen-command→expo/configure-splash-screen到 Expo Modules API 化与 config plugin 化再到将编排逻辑从 expo-router 收编、将 config plugin 从expo/prebuild-config迁回本包——每一次重构都朝着「配置声明式、实现原生化、编排自治化」收敛。对于应用开发者最实用的结论是升级时优先核对最低系统版本与弃用 API 清单定制时优先使用类型化 config plugin 声明backgroundColor/image/resizeMode/dark控制隐藏时机时务必在全局作用域调用preventAutoHideAsync。若需深入实现细节可直接在仓库中阅读 plugin/src 的配置生成逻辑、SplashScreenManager.kt 与 SplashScreenManager.swift 的原生生命周期管理以及对应平台的单元测试用例。【免费下载链接】expoAn open-source framework for making universal native apps with React. Expo runs on Android, iOS, and the web.项目地址: https://gitcode.com/GitHub_Trending/ex/expo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📌 标签:
工业官网
设计趋势
AI 建站
SEO
获取完整报告 →
RELATED ARTICLES
推荐阅读
2026/9/11 11:58:13
电力电子系统中的环流抑制技术与工程实践
2026/9/11 11:58:13
Ionic滚动条全攻略:原理、样式与性能优化
2026/9/11 11:58:13
MicroPython实现硬件级Scatter-Gather DMA链式触发
2026/9/11 12:58:18
RISC-V设备树中断绑定:多父节点路由实战与避坑指南
2026/9/11 12:58:18
基于MovieLens的推荐系统实战:Flask+Spark+ALS全流程实现
2026/9/11 12:58:18
三种虚拟机网络模式深度解析:数据流向决定NAT、桥接与Host-only
2026/9/11 12:58:17
G-Helper 完整使用指南:华硕笔记本轻量级控制工具,单文件替代 Armoury Crate
2026/9/11 12:58:17
AlphaFold预测结果文件怎么读:PDB/MMCIF十分钟上手指南
2026/9/11 12:53:17
BT2106C与Auracast:LE Audio广播落地实战指南
2026/9/11 0:02:03
数据容灾核心指标与实战方案解析
2026/9/11 0:02:03
Huly 平台 ClickUp 任务导入实战指南:从 CSV 导出到一键迁移全流程解析
2026/9/11 0:02:03
PyTorch 构建与代码生成工具链深度解析:从 tools 目录看懂构建流程、autograd/JIT 代码生成与 HIPify 移植
2026/9/11 5:40:15
超人会飞不算本事:系统稳定依赖清晰规则与边界设计
2026/9/11 8:29:24
超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论
2026/9/11 9:11:20
基于CNN的调制信号识别:MATLAB实现时频图分类实战