Android build process
编辑页面
了解 Android 项目如何在 EAS Build 上构建。
For the complete documentation index, see llms.txt. Use this Use this file to discover all available pages.
此页面描述了使用 EAS Build 构建 Android 项目的过程。如果你对构建服务的实现细节感兴趣,可以阅读这篇文章。
Build process
让我们更详细地了解使用 EAS Build 构建 Android 项目的各个步骤。我们会先在你的本地机器上运行一些步骤来准备项目,然后再在远程服务上构建项目。
Local steps
第一阶段发生在你的电脑上。EAS CLI 负责完成以下步骤:
-
如果在 eas.json 中将
cli.requireCommit设置为true,则检查 git index 是否干净 - 这意味着没有未提交的更改。如果不干净,EAS CLI 会提供一个选项,让你提交本地更改,或者中止构建过程。 -
准备构建所需的凭据,除非
builds.android.PROFILE_NAME.withoutCredentials被设置为true。- 根据
builds.android.PROFILE_NAME.credentialsSource的值,凭据将从本地 credentials.json 文件或 EAS 服务器中获取。如果选择了remote模式但尚未存在任何凭据,则会提示你生成新的 keystore。
- 根据
-
创建一个包含仓库副本的 tarball。实际行为取决于你所使用的 VCS workflow。
-
将项目 tarball 上传到一个私有的 Google Cloud Storage(GCS)bucket,并将构建请求发送到 EAS Build。
Remote steps
接下来,这是 EAS Build 接收到你的请求后发生的事情:
-
为构建创建一个新的 Docker 容器。
- 每次构建都会获得自己全新的容器,其中安装了所有构建工具(Java JDK、Android SDK、NDK 等)。
-
从私有 GCS bucket 下载项目 tarball 并解压。
-
如果设置了
NPM_TOKEN,则创建 .npmrc。 -
如果 package.json 中定义了
eas-build-pre-install脚本,则运行它。 -
在项目根目录中运行
npm install(如果存在yarn.lock,则运行yarn install)。 -
运行
npx expo-doctor来诊断项目配置中的潜在问题。 -
managed 项目的额外步骤:运行
npx expo prebuild将项目转换为 bare 项目。此步骤将使用版本化的 Expo CLI。 -
恢复之前保存的缓存,该缓存由 构建配置 中的
cache.key值标识。 -
如果 package.json 中定义了
eas-build-post-install脚本,则运行它。 -
恢复 keystore(如果它包含在构建请求中)。
-
在项目内的 android 目录中运行
./gradlew COMMAND。COMMAND是你在 eas.json 中builds.android.PROFILE_NAME.gradleCommand定义的命令。其默认值为:app:bundleRelease,会生成 AAB(Android App Bundle)。
-
已弃用: 如果 package.json 中定义了
eas-build-pre-upload-artifacts脚本,则运行它。 -
存储 构建配置 中定义的文件和目录缓存。后续构建将恢复此缓存。
-
将应用归档文件上传到 GCS。
- 归档文件路径可以在 eas.json 中通过
builds.android.PROFILE_NAME.applicationArchivePath进行配置。其默认值为android/app/build/outputs/**/*.{apk,aab}。我们使用 glob patterns 进行模式匹配。
- 归档文件路径可以在 eas.json 中通过
-
如果构建成功:如果 package.json 中定义了
eas-build-on-success脚本,则运行它。 -
如果构建失败:如果 package.json 中定义了
eas-build-on-error脚本,则运行它。 -
如果 package.json 中定义了
eas-build-on-complete脚本,则运行它。EAS_BUILD_STATUS环境变量会被设置为finished或errored。 -
如果在构建配置中指定了
buildArtifactPaths,则将构建产物归档文件上传到一个私有 GCS bucket。
Project auto-configuration
每次你想构建一个新的 Android 应用二进制文件时,我们都会验证项目是否已正确设置,以便我们可以在服务器上无缝运行构建过程。这主要适用于 bare 项目,但在构建 managed 项目时也会运行类似的步骤。
Android keystore
Android 要求你使用证书对应用进行签名。该证书存储在你的 keystore 中。Google Play 商店会根据证书来识别应用。这意味着,如果你丢失了 keystore,可能就无法在商店中更新你的应用。不过,借助 Play App Signing,你可以降低丢失 keystore 的风险。
你的应用 keystore 应妥善保密。在任何情况下都不应将其提交到你的仓库中。 Debug keystore 是唯一的例外,因为我们不会使用它们将应用上传到 Google Play 商店。
Configuring Gradle
你的应用二进制文件需要使用 keystore 进行签名。由于我们是在远程服务器上构建项目,因此我们必须想出一种方式,为 Gradle 提供凭据;出于安全原因,这些凭据不会提交到你的仓库中。在远程步骤之一中,我们会将签名配置注入到你的 build.gradle 中。EAS Build 创建 android/app/eas-build.gradle 文件,其内容如下:
// 与 EAS 的构建集成 import java.nio.file.Paths android { signingConfigs { release { // 这是必要的,这样就不需要用户手动定义 release 签名配置 // 如果未定义 release 配置,并且这里不存在它,assembleRelease 的构建将会崩溃 } } buildTypes { release { // 这是必要的,这样就不需要用户手动定义 release 构建类型 } debug { // 这是必要的,这样就不需要用户手动定义 debug 构建类型 } } } tasks.whenTaskAdded { android.signingConfigs.release { def credentialsJson = rootProject.file("../credentials.json"); def credentials = new groovy.json.JsonSlurper().parse(credentialsJson) def keystorePath = Paths.get(credentials.android.keystore.keystorePath); def storeFilePath = keystorePath.isAbsolute() ? keystorePath : rootProject.file("..").toPath().resolve(keystorePath); storeFile storeFilePath.toFile() storePassword credentials.android.keystore.keystorePassword keyAlias credentials.android.keystore.keyAlias if (credentials.android.keystore.containsKey("keyPassword")) { keyPassword credentials.android.keystore.keyPassword } else { // key 密码是 Gradle 所必需的,但 PKCS keystore 没有 // 使用 keystore 密码似乎可以满足这一要求 keyPassword credentials.android.keystore.keystorePassword } } android.buildTypes.release { signingConfig android.signingConfigs.release } android.buildTypes.debug { signingConfig android.signingConfigs.release } }
最重要的部分是 release 签名配置。它配置为从项目根目录下的 credentials.json 文件中读取 keystore 和密码。尽管你不需要自己创建这个文件,但在构建运行之前,EAS Build 会为你创建并填充好你的凭据。
这个文件会像这样在 android/app/build.gradle 中导入:
// ... apply from: "./eas-build.gradle"