裸React Native项目安装Expo模块后Android构建失败求助
React Native裸项目集成Expo Modules后Android构建失败解决方案
问题概况
接触React Native仅3周,在裸RN项目中执行npx install-expo-modules@latest安装Expo及相关模块后,运行npm run android时构建失败,出现三类错误:
- Kotlin Gradle插件在多个子项目重复加载
- MainActivity.java与MainApplication.java的package声明处提示“class, interface, or enum expected”
- 抛出
java.lang.StackOverflowError
已尝试以下方案但未解决:
- 删除
node_modules后重装依赖 - 清理并重建Gradle缓存
- 添加React Native版本强制配置
- 在根
build.gradle中手动添加Kotlin插件
使用Windows系统,相关配置文件如下:
配置文件内容
android/settings.gradle
rootProject.name = 'instagram' apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) include ':app' includeBuild('../node_modules/react-native-gradle-plugin') apply from: new File(["node", "--print", "require.resolve('expo/package.json')"].execute(null, rootDir).text.trim(), "../scripts/autolinking.gradle") useExpoModules()
android/build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { ext { buildToolsVersion = "33.0.0" minSdkVersion = 21 compileSdkVersion = 33 targetSdkVersion = 33 // We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP. ndkVersion = "23.1.7779620" } repositories { google() mavenCentral() } dependencies { classpath("com.android.tools.build:gradle:7.3.1") classpath("com.facebook.react:react-native-gradle-plugin") classpath('org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.10') } }
MainActivity.java
import expo.modules.ReactActivityDelegateWrapper; package com.instagram; import com.facebook.react.ReactActivity; import com.facebook.react.ReactActivityDelegate; import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint; import com.facebook.react.defaults.DefaultReactActivityDelegate; public class MainActivity extends ReactActivity { /** * Returns the name of the main component registered from JavaScript. This is used to schedule * rendering of the component. */ @Override protected String getMainComponentName() { return "instagram"; } /** * Returns the instance of the {@link ReactActivityDelegate}. Here we use a util class {@link * DefaultReactActivityDelegate} which allows you to easily enable Fabric and Concurrent React * (aka React 18) with two boolean flags. */ @Override protected ReactActivityDelegate createReactActivityDelegate() { return new ReactActivityDelegateWrapper(this, BuildConfig.IS_NEW_ARCHITECTURE_ENABLED, new DefaultReactActivityDelegate( this, getMainComponentName(), // If you opted-in for the New Architecture, we enable the Fabric Renderer. DefaultNewArchitectureEntryPoint.getFabricEnabled(), // fabricEnabled // If you opted-in for the New Architecture, we enable Concurrent React (i.e. React 18). DefaultNewArchitectureEntryPoint.getConcurrentReactEnabled() // concurrentRootEnabled )); } }
MainApplication.java
import android.content.res.Configuration; import expo.modules.ApplicationLifecycleDispatcher; import expo.modules.ReactNativeHostWrapper; package com.instagram; import android.app.Application; import com.facebook.react.PackageList; import com.facebook.react.ReactApplication; import com.facebook.react.ReactNativeHost; import com.facebook.react.ReactPackage; import com.facebooak.react.defaults.DefaultNewArchitectureEntryPoint; import com.facebook.react.defaults.DefaultReactNativeHost; import com.facebook.soloader.SoLoader; import java.util.List; public class MainApplication extends Application implements ReactApplication { private final ReactNativeHost mReactNativeHost = new ReactNativeHostWrapper(this, new DefaultReactNativeHost(this) { @Override public boolean getUseDeveloperSupport() { return BuildConfig.DEBUG; } @Override protected List<ReactPackage> getPackages() { @SuppressWarnings("UnnecessaryLocalVariable") List<ReactPackage> packages = new PackageList(this).getPackages(); // Packages that cannot be autolinked yet can be added manually here, for example: // packages.add(new MyReactNativePackage()); return packages; } @Override protected String getJSMainModuleName() { return "index"; } @Override protected boolean isNewArchEnabled() { return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED; } @Override protected Boolean isHermesEnabled() { return BuildConfig.IS_HERMES_ENABLED; } }); @Override public ReactNativeHost getReactNativeHost() { return mReactNativeHost; } @Override public void onCreate() { super.onCreate(); SoLoader.init(this, /* native exopackage */ false); if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { // If you opted-in for the New Architecture, we load the native entry point for this app. DefaultNewArchitectureEntryPoint.load(); } ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); ApplicationLifecycleDispatcher.onApplicationCreate(this); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig); } }
解决方案
1. 修复Java文件语法错误(核心问题)
Java语法规定,package声明必须放在所有import语句之前,否则会触发编译错误,同时修复MainApplication中的拼写错误:
修改后的MainActivity.java
package com.instagram; import expo.modules.ReactActivityDelegateWrapper; import com.facebook.react.ReactActivity; import com.facebook.react.ReactActivityDelegate; import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint; import com.facebook.react.defaults.DefaultReactActivityDelegate; public class MainActivity extends ReactActivity { @Override protected String getMainComponentName() { return "instagram"; } @Override protected ReactActivityDelegate createReactActivityDelegate() { return new ReactActivityDelegateWrapper(this, BuildConfig.IS_NEW_ARCHITECTURE_ENABLED, new DefaultReactActivityDelegate( this, getMainComponentName(), DefaultNewArchitectureEntryPoint.getFabricEnabled(), DefaultNewArchitectureEntryPoint.getConcurrentReactEnabled() )); } }
修改后的MainApplication.java
package com.instagram; import android.content.res.Configuration; import android.app.Application; import expo.modules.ApplicationLifecycleDispatcher; import expo.modules.ReactNativeHostWrapper; import com.facebook.react.PackageList; import com.facebook.react.ReactApplication; import com.facebook.react.ReactNativeHost; import com.facebook.react.ReactPackage; import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint; import com.facebook.react.defaults.DefaultReactNativeHost; import com.facebook.soloader.SoLoader; import java.util.List; public class MainApplication extends Application implements ReactApplication { private final ReactNativeHost mReactNativeHost = new ReactNativeHostWrapper(this, new DefaultReactNativeHost(this) { @Override public boolean getUseDeveloperSupport() { return BuildConfig.DEBUG; } @Override protected List<ReactPackage> getPackages() { List<ReactPackage> packages = new PackageList(this).getPackages(); return packages; } @Override protected String getJSMainModuleName() { return "index"; } @Override protected boolean isNewArchEnabled() { return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED; } @Override protected Boolean isHermesEnabled() { return BuildConfig.IS_HERMES_ENABLED; } }); @Override public ReactNativeHost getReactNativeHost() { return mReactNativeHost; } @Override public void onCreate() { super.onCreate(); SoLoader.init(this, false); if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { DefaultNewArchitectureEntryPoint.load(); } ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); ApplicationLifecycleDispatcher.onApplicationCreate(this); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig); } }
2. 解决Kotlin插件重复加载问题
Expo Modules会自动引入Kotlin插件,手动添加会导致冲突,移除根build.gradle中手动添加的Kotlin插件依赖:
修改后的android/build.gradle依赖部分:
dependencies { classpath("com.android.tools.build:gradle:7.3.1") classpath("com.facebook.react:react-native-gradle-plugin") // 移除该行:classpath('org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.10') }
3. 清理缓存并重新构建
完成上述修改后,执行以下步骤:
- 删除
node_modules:Windows执行rd /s /q node_modules - 清理Gradle缓存:进入android目录执行
gradlew clean - 重装依赖:
npm install - 重新构建:
npm run android
验证
完成以上步骤后,重新运行npm run android即可正常构建。StackOverflowError是由编译错误引发的连锁反应,修复核心语法问题后会自动消失。
内容的提问来源于stack exchange,提问作者Blue339
相关产品推荐
相关产品推荐

