Expo EAS/本地构建失败:Stripe库问题及解决方案
2025-01-30 08:33:01
解决Expo管理项目EAS和本地构建失败的问题
在Expo管理项目中,当使用EAS(Expo Application Services)或者本地构建Android应用时,有时会遇到构建失败的情况。 尤其当涉及到第三方库如@stripe/stripe-react-native
时,问题可能更加棘手。 本文旨在分析此类问题的原因并提供可行的解决方案。
问题分析
构建失败的根本原因往往是R8混淆器在构建Release版本时无法找到 Stripe 库所需的特定类。这些类对于推送配置等特定功能是必要的。 通常,这些类会被 R8 视为未使用的代码而移除,导致运行时错误,即便在开发或物理设备上运行良好。
具体的报错信息中会指出缺少哪些类, 例如:
[RUN_GRADLEW] ERROR: Missing class com.stripe.android.pushProvisioning.PushProvisioningActivity$g
[RUN_GRADLEW] Missing class com.stripe.android.pushProvisioning.PushProvisioningActivityStarter$Args
[RUN_GRADLEW] Missing class com.stripe.android.pushProvisioning.PushProvisioningActivityStarter$Error
...
这意味着 R8 在构建过程中,认为这些 Stripe SDK 中用于推送配置相关的类没有被使用到,因此做了优化将其移除。 但是事实上它们又是必需的,最终导致构建失败。
解决方案
有几种方法可以解决这个问题,关键是告诉 R8 保留这些必要的类,避免被移除。
方案一:添加ProGuard 规则
ProGuard 文件定义了混淆器应保留的类、方法和字段。 我们可以在 android/app/proguard-rules.pro
文件中添加规则,显式告知 R8 需要保留 Stripe 相关的类。
- 创建或修改 proguard-rules.pro : 如果项目根目录下没有
android/app/proguard-rules.pro
文件, 则创建该文件; 如果已存在则打开修改它。 - 添加以下规则 :将下面这些配置项粘贴到
proguard-rules.pro
文件中:
-keep class com.stripe.android.pushProvisioning.** { *; }
-keep class com.stripe.android.googlepay.pushProvisioning.** { *; }
-keep class com.stripe.android.pushProvisioning.PushProvisioningActivity$g
-keep class com.stripe.android.pushProvisioning.PushProvisioningActivityStarter$Args
-keep class com.stripe.android.pushProvisioning.PushProvisioningActivityStarter$Error
-keep class com.stripe.android.pushProvisioning.PushProvisioningActivityStarter
-keep class com.stripe.android.pushProvisioning.PushProvisioningEphemeralKeyProvider
这些规则告诉 R8 不要对 com.stripe.android.pushProvisioning
和 com.stripe.android.googlepay.pushProvisioning
包下的所有类做混淆和优化处理。另外我们还指定了一些明确缺失的类,强制混淆器进行保留。
-
重新构建 : 执行以下命令重新构建Android 应用:
npx eas build -p android --profile preview --local
此方案较为直接,可以有效解决因R8优化引起的类丢失问题,通常用于应对推送配置或者 Google Pay 配置缺失类导致的问题。
方案二:检查和更新依赖库版本
库版本不兼容也可能导致构建问题,确保使用的 @stripe/stripe-react-native
和其他相关库版本是兼容的,并及时进行更新。
-
更新依赖项 : 检查你的
package.json
文件中的@stripe/stripe-react-native
版本,并将其更新为最新版本(可以通过npm outdated
或yarn outdated
查看可升级的版本)。 运行如下命令来升级你的package.json
:npm install @stripe/stripe-react-native@latest
-
重新安装依赖项 : 执行以下命令删除并重新安装依赖,防止缓存引起的问题:
rm -rf node_modules && npm install
-
删除构建缓存 : 执行命令清除缓存文件,保证不会使用到之前的错误缓存:
npm run android:no-cache
-
重新构建 : 执行以下命令重新构建Android 应用:
npx eas build -p android --profile preview --local
库的版本不兼容问题较为常见,及时升级和排查可以解决由于版本差异而带来的冲突问题。
方案三: 使用自定义 gradle 配置
如果通过添加 proguard 规则,并且升级 stripe-react-native
库版本后依然出现构建失败问题,则可以考虑直接在 build.gradle
文件中加入一些 R8 配置选项来跳过混淆过程,这种方式不推荐使用。
- 修改 build.gradle: 在项目目录
android/app/build.gradle
中找到android { ... }
部分, 然后添加packagingOptions
代码块和 R8 相关配置。 例如:
android {
...
packagingOptions {
resources.excludes.add("META-INF/kotlin-*.kotlin_module")
resources.excludes.add("META-INF/LICENSE.md")
}
buildTypes {
release {
// add this
minifyEnabled false // Or use "shrinkResources false" for disable the resource shrink
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
...
}
这里需要将 minifyEnabled
设置为 false
或者使用 shrinkResources false
跳过对资源的优化。
- 同步 Gradle : 确保执行了 gradle 同步命令让修改生效
npx expo run:android
-
重新构建 : 尝试重新构建项目:
npx eas build -p android --profile preview --local
这是一个比较激进的解决方案。禁用 R8 可以解决类丢失的问题,但这通常会导致生成更大的 APK 文件。 建议只作为最后手段尝试,并尽快找到其他合适的方案。
安全建议
- 及时更新依赖 : 定期更新你的依赖库,以修复已知问题并引入新功能。
- 版本控制 : 使用版本控制工具跟踪对
proguard-rules.pro
和build.gradle
的修改。 - 最小权限原则 : 只在必要时添加 ProGuard 规则。
- 谨慎使用 R8 设置 : 理解禁用 R8 的影响,并在可行时找到更好的方案。
解决构建问题往往需要细致地排查和反复尝试。通过以上分析和步骤,应该能够找到解决“EAS和本地构建失败”问题的方法,确保项目的正常构建。