本教程介绍了如何使用 Bazel 构建简单的 Android 应用。
Bazel 支持使用 Android 规则构建 Android 应用。
本教程面向 Windows、macOS 和 Linux 用户,不需要 Bazel 或 Android 应用开发经验。在本教程中,您无需编写任何 Android 代码。
学习内容
在本教程中,您将学习如何:
- 安装 Bazel 和 Android Studio,并下载示例项目,从而设置环境。
- 设置 Bazel 工作区,其中包含应用的源代码和用于标识工作区目录顶级的
MODULE.bazel文件。 - 更新
MODULE.bazel文件,使其包含对所需外部依赖项(如 Android SDK)的引用。 - 创建
BUILD文件。 - 使用 Bazel 构建应用。
- 在 Android 模拟器或实体设备上部署和运行应用。
准备工作
安装 Bazel
在开始本教程之前,请安装以下软件:
- Bazel。如需安装,请按照安装说明操作。
- Android Studio。如需安装,请按照下载 Android Studio的步骤操作。 执行设置向导以下载 SDK 并配置环境。
- (可选)Git。使用
git下载 Android 应用项目。
获取示例项目
对于示例项目,请使用 Bazel 示例代码库中的基本 Android 应用项目。
此应用有一个按钮,点击后会打印问候语:

图 1. Android 应用按钮问候语。
使用 git 克隆代码库(或直接
下载 ZIP 文件):
git clone https://github.com/bazelbuild/examples本教程的示例项目位于 examples/android/tutorial 中。在本教程的其余部分,您将在此目录中执行命令。
查看源文件
查看应用的源文件。
.
├── README.md
└── src
└── main
├── AndroidManifest.xml
└── java
└── com
└── example
└── bazel
├── AndroidManifest.xml
├── Greeter.java
├── MainActivity.java
└── res
├── layout
│ └── activity_main.xml
└── values
├── colors.xml
└── strings.xml
关键文件和目录包括:
| 名称 | 位置 |
|---|---|
| Android 清单文件 | src/main/AndroidManifest.xml 和 src/main/java/com/example/bazel/AndroidManifest.xml |
| Android 源文件 | src/main/java/com/example/bazel/MainActivity.java 和 Greeter.java |
| 资源文件目录 | src/main/java/com/example/bazel/res/ |
使用 Bazel 构建
设置工作区
一个 工作区 是一个目录,其中包含一个或多个软件项目的
源文件,并且其根目录中有一个 MODULE.bazel 文件。
MODULE.bazel 文件可能为空,也可能包含对构建项目所需的 外部
依赖项 的引用。
首先,运行以下命令以创建空的 MODULE.bazel 文件:
| 操作系统 | 命令 |
|---|---|
| Linux、macOS | touch MODULE.bazel |
| Windows(命令提示符) | type nul > MODULE.bazel |
| Windows (PowerShell) | New-Item MODULE.bazel -ItemType file |
运行 Bazel
现在,您可以使用以下命令检查 Bazel 是否正常运行:
bazel info workspace如果 Bazel 输出当前目录的路径,则表示一切正常!如果 MODULE.bazel 文件不存在,您可能会看到类似如下的错误消息:
ERROR: The 'info' command is only supported from within a workspace.
与 Android SDK 集成
Bazel 需要运行 Android SDK
构建工具
来构建应用。这意味着,您需要向您的
MODULE.bazel文件添加一些信息,以便 Bazel 知道在哪里找到这些工具。
将以下行添加到 MODULE.bazel 文件中:
bazel_dep(name = "rules_android", version = "0.5.1")
这将使用 ANDROID_HOME 环境变量引用的路径中的 Android SDK,并自动检测该位置中安装的最高 API 级别和最新版本的构建工具。
您可以将 ANDROID_HOME 变量设置为 Android SDK 的位置。使用 Android Studio 的 SDK
管理器查找已安装 SDK 的路径。假设 SDK 安装在默认位置,您可以使用以下命令设置 ANDROID_HOME 变量:
| 操作系统 | 命令 |
|---|---|
| Linux | export ANDROID_HOME=$HOME/Android/Sdk/ |
| macOS | export ANDROID_HOME=$HOME/Library/Android/sdk |
| Windows(命令提示符) | set ANDROID_HOME=%LOCALAPPDATA%\Android\Sdk |
| Windows (PowerShell) | $env:ANDROID_HOME="$env:LOCALAPPDATA\Android\Sdk" |
上述命令仅为当前 shell 会话设置变量。如需使其永久生效,请运行以下命令:
| 操作系统 | 命令 |
|---|---|
| Linux | echo "export ANDROID_HOME=$HOME/Android/Sdk/" >> ~/.bashrc |
| macOS | echo "export ANDROID_HOME=$HOME/Library/Android/Sdk/" >> ~/.bashrc |
| Windows(命令提示符) | setx ANDROID_HOME "%LOCALAPPDATA%\Android\Sdk" |
| Windows (PowerShell) | [System.Environment]::SetEnvironmentVariable('ANDROID_HOME', "$env:LOCALAPPDATA\Android\Sdk", [System.EnvironmentVariableTarget]::User) |
可选:如果您想将原生代码编译到 Android 应用中,您
还需要下载 Android
NDK
并使用 rules_android_ndk,方法是将以下行添加到您的 MODULE.bazel 文件中:
bazel_dep(name = "rules_android_ndk", version = "0.1.2")
如需了解详情,请参阅将 Android 原生开发套件与 Bazel搭配使用。
无需将 SDK 和 NDK 的 API 级别设置为相同的值。 此页面 包含从 Android 版本到 NDK 支持的 API 级别的映射。
创建 BUILD 文件
A BUILD file 描述了一组构建输出(例如来自 aapt 的已编译 Android 资源或来自 javac 的类文件)及其依赖项之间的关系。这些依赖项可以是工作区中的源文件(Java、C++)或其他构建输出。BUILD 文件使用一种名为 Starlark 的语言编写。
BUILD 文件是 Bazel 中称为“软件包层次结构”的概念的一部分。 软件包层次结构是一种逻辑结构,它覆盖了工作区中的目录结构。每个 软件包 都是一个
目录(及其子目录),其中包含一组相关的源文件
和一个 BUILD 文件。软件包还包含任何子目录,但不包括包含自己的 BUILD 文件的子目录。软件包名称是相对于 MODULE.bazel 文件的 BUILD 文件路径。
请注意,Bazel 的软件包层次结构在概念上与 BUILD 文件所在的 Android 应用目录的 Java 软件包层次结构不同,尽管目录的组织方式可能相同。
对于本教程中的简单 Android 应用,src/main/ 中的源文件构成一个 Bazel 软件包。更复杂的项目可能包含许多嵌套软件包。
添加 android_library 规则
BUILD 文件包含 Bazel 的几种不同类型的声明。最重要的类型是
构建规则,它告知
Bazel 如何从一组源文件或其他依赖项构建中间或最终软件输出。Bazel 提供了两个构建规则:
android_library 和
android_binary,您可以使用它们来
构建 Android 应用。
在本教程中,您将首先使用
android_library 规则告知 Bazel 从应用源代码和资源文件构建 Android 库
模块。然后,您将使用 android_binary 规则告知 Bazel 如何构建 Android 应用软件包。
在 src/main/java/com/example/bazel 目录中创建一个新的 BUILD 文件,并声明一个新的 android_library 目标:
src/main/java/com/example/bazel/BUILD:
package(
default_visibility = ["//src:__subpackages__"],
)
android_library(
name = "greeter_activity",
srcs = [
"Greeter.java",
"MainActivity.java",
],
manifest = "AndroidManifest.xml",
resource_files = glob(["res/**"]),
)
android_library 构建规则包含一组属性,用于指定 Bazel 需要从源文件构建库模块的信息。另请注意,该规则的名称为 greeter_activity。您将在 android_binary 规则中使用此名称作为依赖项来引用该规则。
添加 android_binary 规则
android_binary 规则会为您的应用构建 Android 应用软件包(.apk 文件)。
在 src/main/ 目录中创建一个新的 BUILD 文件,并声明一个新的 android_binary 目标:
src/main/BUILD:
android_binary(
name = "app",
manifest = "AndroidManifest.xml",
deps = ["//src/main/java/com/example/bazel:greeter_activity"],
)
在此,deps 属性引用您添加到上述 BUILD 文件的 greeter_activity 规则的输出。这意味着,当 Bazel 构建此规则的输出时,它会先检查 greeter_activity 库规则的输出是否已构建且为最新版本。如果不是,Bazel 会构建该输出,然后使用该输出构建应用软件包文件。
现在,保存并关闭该文件。
构建应用
尝试构建应用!运行以下命令以构建 android_binary 目标:
bazel build //src/main:appbuild 子命令指示 Bazel 构建后面的
目标。目标指定为 BUILD 文件中的构建规则的名称,以及相对于工作区目录的软件包路径。在此示例中,目标为 app,软件包路径为 //src/main/。
请注意,有时您可以省略软件包路径或目标名称,具体取决于命令行中的当前工作目录和目标的名称。如需详细了解目标标签和路径,请参阅标签。
Bazel 将开始构建示例应用。在构建流程中,其输出将类似于以下内容:
INFO: Analysed target //src/main:app (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
Target //src/main:app up-to-date:
bazel-bin/src/main/app_deploy.jar
bazel-bin/src/main/app_unsigned.apk
bazel-bin/src/main/app.apk
找到构建输出
Bazel 将中间和最终构建操作的输出都放在一组按用户、按工作区输出的目录中。这些目录通过符号链接从项目目录顶层的以下位置链接,其中包含 MODULE.bazel 文件:
bazel-bin存储二进制可执行文件和其他可运行的构建输出bazel-genfiles存储由 Bazel 规则生成的中间源文件bazel-out存储其他类型的构建输出
Bazel 将使用 android_binary 规则生成的 Android .apk 文件存储在 bazel-bin/src/main 目录中,其中子目录名称 src/main 派生自 Bazel 软件包的名称。
在命令提示符下,列出此目录的内容并找到 app.apk 文件:
| 操作系统 | 命令 |
|---|---|
| Linux、macOS | ls bazel-bin/src/main |
| Windows(命令提示符) | dir bazel-bin\src\main |
| Windows (PowerShell) | ls bazel-bin\src\main |
运行应用
现在,您可以使用 bazel
mobile-install 命令从
命令行将应用部署到已连接的 Android 设备或模拟器。此命令使用 Android 调试桥 (adb) 与设备通信。您必须按照 Android Debug
Bridge 中的说明设置
设备以使用 adb,然后才能进行部署。您还可以选择在 Android Studio 中包含的 Android 模拟器上安装应用。请确保模拟器在执行以下命令之前处于运行状态。
输入以下内容:
bazel mobile-install //src/main:app接下来,找到并启动“Bazel 教程应用”:

图 2. Bazel 教程应用。
恭喜!您刚刚安装了第一个使用 Bazel 构建的 Android 应用。
请注意,mobile-install 子命令还支持
--incremental 标志,该标志可用于
仅部署自上次部署以来发生更改的应用部分。
它还支持 --start_app 标志,用于在安装应用后立即启动应用。
深入阅读
如需了解详情,请参阅以下页面:
- GitHub 上的未解决问题
- 详细了解 mobile-install
- 使用 rules_jvm_external 从 Maven 代码库集成外部依赖项,例如 AppCompat、Guava 和 JUnit
- 使用 robolectric-bazel 集成运行 Robolectric 测试。
- 使用 Android 插桩测试 测试应用
- 使用 NDK 将 C 和 C++ 代码集成到 Android 应用中
- 查看更多 Bazel 示例项目:
祝您构建愉快!