React Native与Expo开发Web与安卓应用踩坑记录
前言
本文记录的是 2024 年使用 Expo 开发时遇到的问题。Expo CLI、EAS 和 Android 构建流程都在变化;文中安装命令与限制不应直接当作当前指南。请先查看 EAS CLI 文档 和 Android 构建文档。
由于我们有一个双创项目需要开发一个用于演示远程控制自动化设施的控制面板,同时如果能同时开发网页端和手机端那最好。时间紧任务重,我选择了使用React Native。(至于为什么不是Flutter呢,因为我觉得我写TypeScript的效率比写Dart的效率高)
本文记录了我在开发与构建时踩到的很多的坑,并大致描述了我的折腾历程。
我是使用Expo来创建并管理这个项目的。因为省事。
路由
我从登录界面跳转到主界面的时候用的是router.replace。在Web上能正常工作,但是在Android上没有成功跳转。
最后发现其实是跳转了的,只是因为我把是否已经登录使用boolean存储,设置的默认值是false,而我在还没有把这个值获取出来的时候就去判断了,当然就直接跳转回登录界面了。
不过我还是不太能理解为什么在Web上正常工作,但是Android上就不行了。
构建
当时使用 Expo 的云端构建很方便,但需要排队,所以我倾向于在本机编译。当前 EAS 的构建、额度和本地构建能力可能不同,具体请查看官方文档。
由于我的电脑使用 Windows,我当时选择 WSL 运行 Linux 构建工具。EAS 云端构建与本地构建有不同的平台要求,不要把当时的 WSL 选择理解为当前 Expo 只支持 Linux/macOS。
WSL
由于我之前是在Windows上进行开发的,所以到了WSL里面还需要再配置一遍开发环境。使用apt安装npm。然后安装expo的软件包。
npm install --global eas-cli
Android SDK
安装Android SDK的流程我是参考这篇文章的:https://medium.com/@barcelos.ds/install-android-sdk-in-the-ubuntu-20-04-lts-without-android-studio-1b629924d6c5
总能的来说没有遇到什么非常大的问题。
JDK
目前必须使用JDK 17来进行构建,否则一定会报错。
我一开始是习惯性地安装了GraalVM,然后编译失败。最后在sdkman!中换上了Oracle JDK才把问题解决掉。
当时出现的报错信息是这样的:
[RUN_GRADLEW] FAILURE:
[RUN_GRADLEW] Build failed with an exception.
[RUN_GRADLEW] * What went wrong:
[RUN_GRADLEW] Execution failed for task ':react-native-async-storage_async-storage:compileReleaseJavaWithJavac'.
[RUN_GRADLEW] > Could not resolve all files for configuration ':react-native-async-storage_async-storage:androidJdkImage'.
[RUN_GRADLEW] > Failed to transform core-for-system-modules.jar to match attributes {artifactType=_internal_android_jdk_image, org.gradle.libraryelements=jar, org.gradle.usage=java-runtime}.
[RUN_GRADLEW] > Execution failed for JdkImageTransform: /home/iruanp/android-sdk/platforms/android-34/core-for-system-modules.jar.
[RUN_GRADLEW] > Error while executing process /home/iruanp/.sdkman/candidates/java/17.0.11-graal/bin/jlink with arguments {--module-path /home/iruanp/.gradle/caches/transforms-4/d665602e84a280c1d9cc11bc0b8c3a7f-d8f2c8fe-52af-45f8-ac8c-d4af7195b6f6/transformed/output/temp/jmod --add-modules java.base --output /home/iruanp/.gradle/caches/transforms-4/d665602e84a280c1d9cc11bc0b8c3a7f-d8f2c8fe-52af-45f8-ac8c-d4af7195b6f6/transformed/output/jdkImage --disable-plugin system-modules}
目标
iOS应用我没有尝试过,因为我没有苹果的开发者账户。
当时我希望生成按 ABI 拆分的 APK,而默认产物和我的期望不一致。Android 的 AAB/APK 输出和 ABI 拆分取决于 EAS 配置及原生 Gradle 设置;当前 Expo 文档支持配置 Android 构建产物,遇到类似需求时应先查看 APK 配置说明 和项目的 Gradle 配置。