从命令行构建您的应用

您可以使用 Gradle 包装器 命令行工具执行 Android 项目中可用的所有构建任务。它以 Windows 的批处理文件 (gradlew.bat) 和 Linux 和 Mac 的 shell 脚本 (gradlew.sh) 的形式提供,并且可以从您使用 Android Studio 创建的每个项目的根目录访问。

要使用包装器运行任务,请从终端窗口使用以下命令之一(在 Android Studio 中,选择 **查看 > 工具窗口 > 终端**)

  • 在 Windows 命令提示符中
    gradlew task-name
  • 在 Mac、Linux 或 Windows PowerShell 中
    ./gradlew task-name

要查看项目中所有可用构建任务的列表,请执行 tasks

gradlew tasks

此页面的其余部分描述了使用 Gradle 包装器构建和运行应用的基础知识。有关如何设置 Android 构建的更多信息,请参阅 配置您的构建

如果您希望使用 Android Studio 工具而不是命令行工具,请参阅 构建和运行您的应用

关于构建类型

默认情况下,每个 Android 应用都提供两种构建类型:一种用于调试应用的 _debug_ 构建和一种用于向用户发布应用的 _release_ 构建。在将每个构建的结果输出部署到设备之前,必须使用证书对其进行签名。调试构建会自动使用 SDK 工具提供的调试密钥进行签名(它不安全,您不能使用它发布到 Google Play 商店),而发行版构建必须使用您自己的私钥进行签名。

如果您要构建发行版应用,则还必须 对应用进行签名 ,并使用相应的签名密钥。但是,如果您刚开始使用,则可以通过 构建调试 APK 快速在模拟器或已连接的设备上运行应用。

您也可以在 build.gradle.kts 文件中定义自定义构建类型,并通过包含 debuggable true 将其配置为调试构建。有关更多信息,请参阅 配置构建变体

构建和部署 APK

虽然构建应用包是打包应用并将其上传到 Play Console 的最佳方式,但当您需要快速测试调试版本或与他人共享应用作为可部署工件时,构建 APK 更为合适。

构建调试 APK

对于即时应用测试和调试,您可以构建调试 APK。调试 APK 使用 SDK 工具提供的调试密钥进行签名,并允许通过adb进行调试。

要构建调试 APK,请打开命令行并导航到项目目录的根目录。要启动调试构建,请调用assembleDebug任务

gradlew assembleDebug

这会在project_name/module_name/build/outputs/apk/中创建一个名为module_name-debug.apk的 APK。该文件已使用调试密钥签名并与zipalign对齐,因此您可以立即将其安装到设备上。

或者,要构建 APK 并立即将其安装到正在运行的模拟器或已连接的设备上,请调用installDebug

gradlew installDebug

上述任务名称中的“Debug”部分只是构建变体名称的驼峰式版本,因此可以用您想要组装或安装的任何构建类型或变体替换它。例如,如果您有一个“demo”产品风格,则可以使用assembleDemoDebug任务构建调试版本。

要查看每个变体可用的所有构建和安装任务(包括卸载任务),请运行tasks任务。

另请参见有关如何在模拟器上运行您的应用在设备上运行您的应用的部分。

构建发行版包或 APK

准备好发布和分发您的应用时,必须构建一个使用您的私钥签名的发行版包或 APK。有关更多信息,请转到有关如何从命令行签名您的应用的部分。

将您的应用部署到模拟器

要使用 Android 模拟器,您必须使用 Android Studio创建一个 Android 虚拟设备 (AVD)

拥有 AVD 后,启动 Android 模拟器并按如下所示安装您的应用

  1. 在命令行中,导航到android_sdk/tools/并通过指定您的 AVD 来启动模拟器

    emulator -avd avd_name

    如果您不确定 AVD 名称,请执行emulator -list-avds

  2. 现在,您可以使用如何在构建调试 APK部分中提到的 Gradle install 任务之一或adb工具来安装您的应用。

    如果使用开发者预览版 SDK 构建 APK(如果targetSdkVersion是字母而不是数字),则必须在install命令中包含-t选项以安装测试 APK。

    adb install path/to/your_app.apk
    

    您构建的所有 APK 都保存在project_name/module_name/build/outputs/apk/中。

有关更多信息,请参见在 Android 模拟器上运行应用

将您的应用部署到物理设备

在您可以在设备上运行应用之前,必须在您的设备上启用**USB 调试**。您可以在**设置 > 开发者选项**下找到此选项。

注意:在 Android 4.2 及更高版本中,**开发者选项**默认情况下是隐藏的。要使其可用,请转到**设置 > 关于手机**并点击**内部版本号**七次。返回到上一屏幕以查找**开发者选项**。

设备设置完毕并通过 USB 连接后,您可以使用如何在构建调试 APK部分中提到的 Gradle install 任务之一或adb工具来安装您的应用

adb -d install path/to/your_app.apk

您构建的所有 APK 都保存在project_name/module_name/build/outputs/apk/中。

有关更多信息,请参见在硬件设备上运行应用

构建应用包

Android 应用包包含您应用的所有已编译代码和资源,但会将 APK 生成和签名推迟到 Google Play。与 APK 不同,您不能直接将应用包部署到设备。因此,如果您想快速测试或与其他人共享 APK,则应改为构建 APK

构建应用包最简单的方法是使用 Android Studio。但是,如果您需要从命令行构建应用包,则可以使用 Gradle 或bundletool,如下节所述。

使用 Gradle 构建应用包

如果您希望从命令行生成应用包,请在应用的基础模块上运行bundleVariant Gradle 任务。例如,以下命令将为基础模块的调试版本构建应用包:

./gradlew :base:bundleDebug

如果您想构建一个签名的包以上传到 Play Console,则需要首先使用您的应用签名信息配置基础模块的build.gradle.kts文件。要了解更多信息,请转到有关如何配置 Gradle 以签名您的应用的部分。然后,您可以例如构建应用的发行版,Gradle 会自动生成应用包并使用您在build.gradle.kts文件中提供的签名信息对其进行签名。

如果您希望将应用包签名作为单独的步骤,则可以使用jarsigner从命令行签名您的应用包。构建应用包的命令是:

jarsigner -keystore pathToKeystore app-release.aab keyAlias

使用 bundletool 构建应用包

bundletool是一个命令行工具,Android Studio、Android Gradle 插件和 Google Play 使用它将应用的已编译代码和资源转换为应用包,并从这些包中生成可部署的 APK。

因此,虽然使用bundletool测试应用包并在本地重新创建 Google Play 如何生成 APK 很有用,但您通常不需要调用bundletool来构建应用包本身——您应该改为使用 Android Studio 或 Gradle 任务,如前几节所述。

但是,如果您不想使用 Android Studio 或 Gradle 任务来构建包——例如,如果您使用自定义构建工具链——您可以使用命令行中的bundletool从预编译的代码和资源构建应用包。如果您尚未这样做,请从 GitHub 存储库下载bundletool

本节介绍如何打包应用的已编译代码和资源,以及如何使用命令行中的bundletool将它们转换为 Android 应用包。

生成 proto 格式的清单和资源

bundletool需要有关您的应用项目的一些信息,例如应用的清单和资源,这些信息必须采用Google 的 Protocol Buffer 格式——也称为“protobuf”并使用*.pb文件扩展名。Protobufs 提供了一种与语言无关、与平台无关且可扩展的机制来序列化结构化数据——它类似于 XML,但更小、更快且更简单。

下载 AAPT2

您可以使用来自Google Maven 存储库的最新版本的 AAPT2 以 protobuf 格式生成应用的清单文件和资源表。

要从 Google 的 Maven 存储库下载 AAPT2,请按如下步骤操作

  1. 存储库索引中导航到**com.android.tools.build > aapt2**。
  2. 复制最新版本 AAPT2 的名称。
  3. 将您复制的版本名称插入到以下 URL 中并指定您的目标操作系统:https://dl.google.com/dl/android/maven2/com/android/tools/build/aapt2/aapt2-version/aapt2-aapt2-version-[windows | linux | osx].jar

    例如,要下载适用于 Windows 的 3.2.0-alpha18-4804415 版本,您将使用:https://dl.google.com/dl/android/maven2/com/android/tools/build/aapt2/3.2.0-alpha18-4804415/aapt2-3.2.0-alpha18-4804415-windows.jar

  4. 在浏览器中导航到该 URL——AAPT2 应很快开始下载。

  5. 解压您刚刚下载的 JAR 文件。

使用 AAPT2 使用以下命令编译应用的资源

aapt2 compile \
project_root/module_root/src/main/res/drawable/Image1.png \
project_root/module_root/src/main/res/drawable/Image2.png \
-o compiled_resources/

在链接阶段,AAPT2 将您各种已编译的资源链接到单个 APK 中,通过包含--proto-format标志,指示 AAPT2 将应用的清单和已编译资源转换为 protobuf 格式,如下所示

aapt2 link --proto-format -o output.apk \
-I android_sdk/platforms/android_version/android.jar \
--manifest project_root/module_root/src/main/AndroidManifest.xml \
-R compiled_resources/*.flat \
--auto-add-overlay

然后,您可以从输出 APK 中提取内容,例如应用的AndroidManifest.xmlresources.pb和其他资源文件——现在采用 protobuf 格式。在准备bundletool构建应用包所需的输入时,您需要这些文件,如下一节所述。

打包预编译的代码和资源

在使用bundletool为您的应用生成应用包之前,您必须首先提供 ZIP 文件,每个文件都包含给定应用模块的已编译代码和资源。每个模块的 ZIP 文件的内容和组织方式与Android 应用包格式非常相似。例如,您应该为应用的基础模块创建一个base.zip文件,并按如下所示组织其内容

文件或目录 说明
manifest/AndroidManifest.xml 模块的 protobuf 格式清单。
dex/... 包含一个或多个应用已编译 DEX 文件的目录。这些文件应命名如下:classes.dexclasses2.dexclasses3.dex等。
res/... 包含所有设备配置的protobuf格式的模块资源。子目录和文件应与典型APK的组织方式类似。
root/...assets/...lib/... 这些目录与Android应用包格式部分中描述的目录相同。
resources.pb 应用的protobuf格式资源表。

准备好应用每个模块的ZIP文件后,可以将其传递给bundletool来构建应用包,如下节所述。

使用bundletool构建应用包

要构建应用包,可以使用bundletool build-bundle命令,如下所示

bundletool build-bundle --modules=base.zip --output=mybundle.aab

下表更详细地描述了build-bundle命令的标志

标志 说明
--modules=path-to-base.zippath-to-module2.zippath-to-module3.zip 指定bundletool应该用来构建应用包的模块ZIP文件列表。
--output=path-to-output.aab 指定输出*.aab文件的路径和文件名。
--config=path-to-BundleConfig.json 指定可选配置文件的路径,可以使用该文件自定义构建过程。要了解更多信息,请参阅关于自定义下游APK生成的部分。
--metadata-file=target-bundle-path:local-file-path 指示bundletool在应用包中打包可选的元数据文件。可以使用此文件包含数据,例如ProGuard映射或应用DEX文件的完整列表,这些数据可能对工具链中的其他步骤或应用商店有用。

target-bundle-path指定应用包根目录中要打包元数据文件的相对路径,local-file-path指定本地元数据文件的路径。

自定义下游APK生成

应用包包含一个BundleConfig.pb文件,该文件提供应用商店(如Google Play)从包中生成APK时所需的元数据。bundletool会为您创建此文件,但可以在BundleConfig.json文件中配置元数据的一些方面,并将其传递给bundletool build-bundle命令——bundletool稍后会将此文件转换为protobuf版本,并将其与每个应用包中包含的protobuf版本合并。

例如,可以控制要启用或禁用的配置APK类别。以下BundleConfig.json文件示例禁用了每个目标不同语言的配置APK(即,所有语言的资源都包含在其各自的基础或功能APK中)

{
  "optimizations": {
    "splitsConfig": {
      "splitDimension": [{
        "value": "LANGUAGE",
        "negate": true
      }]
    }
  }
}

BundleConfig.json文件中,还可以指定使用glob模式打包APK时要保留未压缩的文件类型,如下所示

{
  "compression": {
    "uncompressedGlob": ["res/raw/**", "assets/**.uncompressed"]
  }
}

请记住,默认情况下,bundletool不会压缩应用的原生库(Android 6.0或更高版本)和资源表(resources.arsc)。有关可以在BundleConfig.json中配置的内容的完整说明,请检查bundletool config.proto文件,该文件使用Proto3语法编写。

从应用包部署应用

如果已构建并签署了应用包,请使用bundletool生成APK并将其部署到设备。

从命令行签名应用

不需要Android Studio来签名应用。可以使用命令行,对APK使用apksigner,对应用包使用jarsigner,或配置Gradle在构建过程中对其进行签名。无论哪种方式,都需要首先使用keytool生成私钥,如下所示

keytool -genkey -v -keystore my-release-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias my-alias

以上示例会提示输入密钥库和密钥的密码,以及密钥的“区分名称”字段。然后它会将密钥库生成名为my-release-key.jks的文件,并将其保存在当前目录中(可以将其移动到任何位置)。密钥库包含一个有效期为10,000天的密钥。

现在,可以手动签名APK或应用包,也可以配置Gradle在构建过程中签名应用,如下节所述。

从命令行手动签名应用

如果要从命令行签名应用包,可以使用jarsigner。如果要签名APK,则需要使用zipalignapksigner,如下所述。

  1. 打开命令行—在Android Studio中,选择**查看>工具窗口>终端**—并导航到未签名APK所在的目录。
  2. 使用zipalign对齐未签名的APK

    zipalign -v -p 4 my-app-unsigned.apk my-app-unsigned-aligned.apk
    

    zipalign确保所有未压缩的数据相对于文件开头的特定字节对齐,这可以减少应用消耗的RAM量。

  3. 使用apksigner使用私钥签名APK

    apksigner sign --ks my-release-key.jks --out my-app-release.apk my-app-unsigned-aligned.apk
    

    此示例在签名后,将已签名的APK输出到my-app-release.apk,使用存储在单个密钥库文件my-release-key.jks中的私钥和证书。

    apksigner工具支持其他签名选项,包括使用单独的私钥和证书文件签名APK文件,以及使用多个签名者签名APK。有关更多详细信息,请参阅apksigner参考。

    注意:要使用apksigner工具,必须安装Android SDK Build Tools的24.0.3或更高版本。可以使用SDK Manager更新此软件包。

  4. 验证APK是否已签名

    apksigner verify my-app-release.apk
    

配置Gradle签名应用

打开模块级build.gradle.kts文件,并添加包含storeFilestorePasswordkeyAliaskeyPassword条目的signingConfigs {}块,然后将该对象传递给构建类型中的signingConfig属性。例如

Kotlin

android {
    ...
    defaultConfig { ... }
    signingConfigs {
        create("release") {
            // You need to specify either an absolute path or include the
            // keystore file in the same directory as the build.gradle file.
            storeFile = file("my-release-key.jks")
            storePassword = "password"
            keyAlias = "my-alias"
            keyPassword = "password"
        }
    }
    buildTypes {
        getByName("release") {
            signingConfig = signingConfigs.getByName("release")
            ...
        }
    }
}

Groovy

android {
    ...
    defaultConfig { ... }
    signingConfigs {
        release {
            // You need to specify either an absolute path or include the
            // keystore file in the same directory as the build.gradle file.
            storeFile file("my-release-key.jks")
            storePassword "password"
            keyAlias "my-alias"
            keyPassword "password"
        }
    }
    buildTypes {
        release {
            signingConfig signingConfigs.release
            ...
        }
    }
}

现在,调用Gradle任务构建应用时,Gradle会为您签名应用(并运行zipalign)。

此外,由于已使用签名密钥配置了发行版构建,因此该构建类型可以使用“install”任务。因此,可以使用installRelease任务构建、对齐、签名并将发行版APK安装到模拟器或设备上。

使用私钥签名的应用已准备好分发,但应首先阅读有关如何发布应用的更多信息,并查看Google Play启动清单