React Native Expo SDK52预览构建版无限卡在启动屏求助
Expo SDK 52 预览构建无限卡启动屏问题排查与解决
核心问题分析
开发构建和Expo Go正常,但预览构建卡启动屏,说明问题出在生产构建环境的资源加载、异步逻辑阻塞或配置缺失,和页面代码无关(你已删至Hello World仍复现)。结合你提供的代码,主要排查以下几点:
具体排查与修复步骤
1. 移除全局的启动屏阻止调用
你在组件外部全局调用了SplashScreen.preventAutoHideAsync(),这在构建环境中可能执行时机过早,和Expo的启动生命周期冲突,直接删掉这行代码,只保留组件内部useEffect里的调用。
2. 给异步任务加超时,避免无限pending
代码中Promise.all里的三个任务只要有一个无限pending,就会导致loaded永远不会设为true,启动屏一直显示。给每个任务加超时兜底:
首先封装超时工具函数:
const withTimeout = (promise, timeoutMs, errorMsg) => { return Promise.race([ promise, new Promise((_, reject) => setTimeout(() => reject(new Error(errorMsg)), timeoutMs)) ]); };
然后修改prepare里的Promise.all:
await Promise.all([ // 字体加载超时5秒 withTimeout( Font.loadAsync({ 'Poppins': require('./fonts/Poppins-Regular.ttf') }), 5000, '字体加载超时' ), // 推送注册超时10秒 withTimeout( registerForPushNotificationsAsync().then(token => setPushToken(token)), 10000, '推送注册超时' ), // Auth监听加双重兜底:8秒自动resolve,外层超时10秒 withTimeout( new Promise(resolve => { const unsubscribe = onAuthStateChanged(auth, user => { unsubscribe(); resolve(user); }); // 防止Auth无回调,8秒后强制结束监听 setTimeout(() => { unsubscribe(); resolve(null); }, 8000); }), 10000, 'Auth状态监听超时' ) ]);
3. 检查构建环境的资源与配置
- 字体资源:确认
./fonts/Poppins-Regular.ttf存在,且在app.json的assets字段中声明:
构建前执行"assets": ["./fonts/"]expo prebuild确保资源被正确打包。 - 推送通知:预览构建需要配置iOS推送证书/Android FCM密钥,如果暂时不需要推送,直接注释掉这个任务,测试是否还卡屏。
- Firebase Auth:检查
google-services.json(Android)/GoogleService-Info.plist(iOS)是否正确添加到项目,且构建时被包含,配置错误会导致Auth监听无回调。
4. 添加全局兜底超时
给整个启动流程加一个全局超时,确保即使所有逻辑都卡住,也能强制隐藏启动屏:
useEffect(() => { // 15秒兜底超时,防止所有逻辑阻塞 const globalTimeout = setTimeout(async () => { await SplashScreen.hideAsync(); setAppIsReady(true); }, 15000); async function prepare() { // ... 原有prepare逻辑,包含上面修改后的Promise.all } prepare(); return () => clearTimeout(globalTimeout); }, []);
5. 查看构建日志定位具体错误
执行expo build:preview --verbose构建,或者在设备上查看原生日志:
- iOS:用Xcode打开构建后的项目,查看控制台输出
- Android:用
adb logcat | grep Expo过滤日志
日志里会显示具体的错误(比如字体找不到、Auth初始化失败等),这是最直接的排查方式。
内容的提问来源于stack exchange,提问作者Kyle Mabaso
相关产品推荐
相关产品推荐

