React Native Expo构建APK后无报错崩溃问题求助
Expo构建APK后模拟器/真机崩溃,但
expo start运行正常的解决方案 问题描述
React Native Expo项目通过expo build:android生成APK后,在模拟器和真机安装启动均无报错直接崩溃,但使用expo start(包括开发模式和生产模式)运行时完全正常,尝试多种方案后仍未解决。
项目配置文件
Package.json
{ "main": "index.js", "scripts": { "start": "expo start", "android": "expo start --android", "ios": "expo start --ios", "web": "expo start --web", "eject": "expo eject", "test": "node ./node_modules/jest/bin/jest.js --watchAll" }, "jest": { "preset": "jest-expo" }, "dependencies": { "@react-native-community/netinfo": "8.2.0", "expo": "^45.0.0", "expo-asset": "~8.5.0", "expo-font": "~10.1.0", "expo-location": "~14.2.2", "expo-network": "~4.2.0", "expo-splash-screen": "~0.15.1", "expo-status-bar": "~1.3.0", "expo-updates": "~0.13.3", "firebase": "^9.9.0", "map-nearest-location": "^1.1.4", "react": "17.0.2", "react-dom": "17.0.2", "react-native": "0.68.2", "react-native-beautiful-timeline": "^0.1.1", "react-native-gesture-handler": "~2.2.1", "react-native-link": "^4.1.0", "react-native-maps": "0.30.2", "react-native-safe-area-context": "4.2.4", "react-native-safe-area-view": "^1.1.1", "react-native-screens": "~3.11.1", "react-native-timeline-flatlist": "^0.8.0", "react-native-vector-icons": "^9.1.0", "react-native-web": "0.17.7", "react-navigation": "^4.4.4", "react-navigation-stack": "^2.10.4", "react-redux": "^7.2.6", "redux": "^4.1.2", "redux-thunk": "^2.4.1" }, "devDependencies": { "@babel/core": "^7.12.9", "babel-preset-expo": "~9.1.0", "eslint": "^8.10.0", "jest-expo": "^45.0.0", "prettier": "^2.5.1" }, "private": true }
app.json
{ "expo": { "name": "demoapp", "slug": "demoapp", "version": "1.0.0", "orientation": "portrait", "icon": "./assets/icon.png", "splash": { "image": "./assets/images/splash.png", "resizeMode": "contain", "backgroundColor": "#ffffff" }, "updates": { "fallbackToCacheTimeout": 0 }, "assetBundlePatterns": [ "**/*" ], "ios": { "supportsTablet": true }, "android": { "package": "com.demo.demoapp", "versionCode": 1 } } }
App.js
import React, {useCallback, useEffect, useState} from 'react'; import {Provider} from 'react-redux'; import {Platform, StatusBar, StyleSheet, View, LogBox} from 'react-native'; import {AppLoading} from 'expo'; import AppNavigator from './navigation/AppNavigator'; import * as SplashScreen from 'expo-splash-screen'; import * as Font from 'expo-font'; import store from './modules'; export default function App() { const [appIsReady, setAppIsReady] = useState(false); useEffect(() => { // Ignore log notification by message: LogBox.ignoreLogs(['Warning: ...']); // Ignore all log notifications: LogBox.ignoreAllLogs(); async function hideLoading() { return await SplashScreen.hideAsync(); } async function prepare() { try { await SplashScreen.preventAutoHideAsync(); // Pre-load fonts, make any API calls you need to do here await Font.loadAsync({ 'open-sans': require('./assets/fonts/OpenSans-Regular.ttf'), 'open-sans-bold': require('./assets/fonts/OpenSans-Bold.ttf'), }).then(async () => { await new Promise((resolve) => setTimeout(resolve, 1000)).then(() => { setAppIsReady(true); }); }); } catch (e) { console.warn(e); } finally { setAppIsReady(true); } } const result = prepare(); result.then(() => { const isHide = hideLoading(); isHide.then(() => { setAppIsReady(true); }); }); }); if (!appIsReady) { return null; } return ( <Provider store={store}> <AppNavigator /> </Provider> ); } const styles = StyleSheet.create({ container: { flex: 1, paddingTop: 20, }, });
排查与解决方案
1. 修复App.js异步逻辑混乱问题
当前App.js的useEffect存在重复设置appIsReady、异步执行顺序混乱、无依赖数组导致重复触发的问题,这是APK启动崩溃的核心原因之一。修改后的代码:
useEffect(() => { LogBox.ignoreAllLogs(); async function prepareAndLaunch() { try { await SplashScreen.preventAutoHideAsync(); // 预加载字体 await Font.loadAsync({ 'open-sans': require('./assets/fonts/OpenSans-Regular.ttf'), 'open-sans-bold': require('./assets/fonts/OpenSans-Bold.ttf'), }); // 可选:移除1秒延迟,避免不必要的等待 await new Promise(resolve => setTimeout(resolve, 1000)); } catch (e) { console.error(e); } finally { await SplashScreen.hideAsync(); setAppIsReady(true); } } prepareAndLaunch(); }, []); // 空依赖数组确保只执行一次初始化逻辑
- 合并分散的异步操作,统一控制启动流程
- 添加空依赖数组,避免
useEffect无限循环触发 - 在
finally中统一设置启动完成状态,保证状态唯一且正确
2. 移除/替换兼容性有问题的第三方库
react-native-link:该库已废弃,直接替换为React Native官方的LinkingAPI,避免潜在的编译或运行时冲突react-native-beautiful-timeline、react-native-timeline-flatlist:这类小众库可能未适配RN 0.68.2和Expo 45,临时移除这两个库后重新构建APK测试,若崩溃消失则需替换为更稳定的组件
3. 补充Android权限配置
expo-location需要明确声明权限,否则APK启动时会因权限缺失崩溃,在app.json的android字段中添加权限:
"android": { "package": "com.demo.demoapp", "versionCode": 1, "permissions": [ "ACCESS_COARSE_LOCATION", "ACCESS_FINE_LOCATION" ] }
4. 清除缓存后重新构建
执行以下命令清除Expo和项目缓存,避免旧缓存导致的构建异常:
expo r -c expo build:android -t apk --clear-cache
5. 查看崩溃日志定位根源
通过Android Studio的Logcat查看真机崩溃日志:
- 开启真机USB调试并连接电脑
- 打开Android Studio,进入Logcat面板
- 过滤应用包名
com.demo.demoapp,查看崩溃时的错误堆栈,精准定位问题模块
内容的提问来源于stack exchange,提问作者Hohenheim
相关产品推荐
相关产品推荐

