Android SDK 并不是一个单一安装包,而是一个由命令行工具、平台版本、构建工具、平台工具、系统镜像和 NDK 等模块组成的集合。很多构建失败、CI 环境不可复现以及下载耗时过长的问题,本质都是没有把这些模块当成可版本化的依赖来管理。如果只在 Android Studio 中点击 SDK Manager,不仅难以记录具体安装了什么版本,还无法在无 GUI 的服务器上完成自动化部署。

要管理好 SDK,必须先理解它的目录结构。一个典型的 SDK 根目录下会包含 platforms、build-tools、cmdline-tools、platform-tools、ndk 和 emulator 等子目录。其中 platforms 存放各版本 android.jar 和资源,build-tools 提供 aapt2、d8、apksigner 等编译打包程序,platform-tools 负责 adb 和 fastboot,cmdline-tools 则包含 sdkmanager 和 avdmanager 这类命令行管理工具。它们各自独立发版,因此需要像管理项目依赖一样精确锁定版本。
为什么 GUI 安装方式不适合团队协作
Android Studio 自带的 SDK Manager 对个人开发很友好,可视化勾选组件即可完成安装,但它并不适合需要多人协作和自动化构建的场景。首先,GUI 操作无法固化成脚本,新成员加入项目时只能手动点击安装,版本选择很容易出现不一致。其次,CI 服务器通常没有图形界面,即使可以通过远程桌面操作,也不适合在流水线中重复执行。最后,GUI 安装过程默认使用官方下载源,在网络条件一般的环境中经常出现下载缓慢或超时。
团队协作的核心诉求是可复现。也就是说,任何一台新电脑或 CI 机器都应当能够通过一条命令、一个脚本,安装出与现有环境完全一致的 SDK 版本组合。这不仅包括主版本,还要细化到 build-tools 的具体版本,例如 34.0.0 和 34.0.1 在编译行为上可能存在差异。GUI 操作很难长期保持这种一致性。
使用 sdkmanager 命令行实现可复现安装
命令行管理 SDK 的第一步是安装 cmdline-tools。可以从官方下载对应平台的压缩包,解压后得到 cmdline-tools 目录,然后将其放入 SDK 根目录并命名为 latest。完成这一步后,就可以使用 sdkmanager 命令来安装、更新和卸载各个 SDK 组件。
# 查看已安装和可用的包 sdkmanager --list # 安装指定版本的 platform 和 build-tools sdkmanager --install "platforms;android-34" "build-tools;34.0.0" "platform-tools" # 安装最新版命令行工具 sdkmanager --install "cmdline-tools;latest"
在脚本中使用 sdkmanager 时,建议明确写出每一个组件的版本号。需要同时安装多个组件时,可以把组件名作为多个参数传入,也可以逐行执行。版本号写入脚本后就形成了事实上的锁文件,后续升级应当通过修改脚本来完成,而不是在 GUI 中随手更新。
许可证问题是命令行安装中容易忽略的环节。未接受许可证时,sdkmanager 会拒绝安装对应组件。可以通过下面的命令一次性接受所有许可证,适合在 CI 初始化阶段使用。
yes | sdkmanager --licenses
通过环境变量统一 SDK 根目录
Android 构建工具通常通过 ANDROID_HOME 或 ANDROID_SDK_ROOT 环境变量定位 SDK 路径。旧版本工具链主要识别 ANDROID_HOME,而较新的工具链推荐使用 ANDROID_SDK_ROOT。为了兼容不同版本的构建工具,建议同时设置两个变量,并指向同一个目录。
在 Windows 平台上设置环境变量时,可以使用 setx 命令,但要注意路径中的反斜杠必须原样保留。例如将 SDK 放在 C:\Android\sdk,可以这样设置:
setx ANDROID_HOME "C:\Android\sdk" setx ANDROID_SDK_ROOT "C:\Android\sdk"
在 Linux 或 macOS 环境中,则通过 export 写入 shell 配置文件。统一环境变量不仅方便 Gradle 查找 SDK,还能让各类第三方工具和命令行程序共享同一套 SDK,避免机器上出现多份重复安装。
在 Gradle 中锁定编译版本
Gradle 构建时会读取模块中的 compileSdk、minSdk 和 targetSdk 等配置。其中 compileSdk 决定编译时使用的 Android 平台版本,必须与 SDK 中已安装的 platforms 版本匹配。如果缺少对应平台,Gradle 会尝试自动下载,但自动下载需要满足两个条件:一是 SDK 目录可写,二是许可已经接受。
android {
compileSdk 34
defaultConfig {
minSdk 23
targetSdk 34
}
buildToolsVersion "34.0.0"
}
这里显式声明 buildToolsVersion 可以确保所有开发者使用完全一致的构建工具。如果项目没有声明该属性,Gradle 会根据 AGP 版本自动选择默认 build-tools 版本,这在团队中可能因为 AGP 版本差异而产生不同结果。建议至少在发布分支中锁定 buildToolsVersion。
如果不想在 build.gradle 中硬编码本机 SDK 路径,可以使用 local.properties 文件指定路径。该文件通常不提交到版本控制,每个开发者根据本机环境自行维护。文件内容如下:
sdk.dir=C:\Android\sdk
使用镜像和代理加速 SDK 下载
官方下载源在全球范围内速度差异较大,国内团队通常需要配置镜像或代理。部分云服务商和开源社区提供 Android SDK 镜像,可以通过修改 sdkmanager 的下载源或使用代理参数来加速。临时代理可以直接附加在命令中,例如:
sdkmanager --proxy=http --proxy_host=127.0.0.1 --proxy_port=7890 --install "platforms;android-34"
如果公司内部有统一的 HTTP 代理,建议将代理配置写入环境变量或 CI 的构建参数,避免每次手动输入。对于已经完成下载的 SDK,可以将其整体打包归档,在需要时直接解压使用。这样既能保证版本一致性,又能显著减少重复下载时间。
缓存策略还应当包括 Gradle 的依赖缓存。即使 SDK 已经就绪,Gradle 仍可能从网络获取 AGP 和第三方依赖。把常用依赖提前缓存到本地仓库,或使用公司内部 Maven 仓库,可以进一步降低构建环境初始化时间。
CI 环境中的 SDK 初始化与缓存
在 CI 流水线中,SDK 的安装和缓存应当作为独立步骤执行。以 GitHub Actions 为例,可以在作业启动后先设置 JDK,再恢复缓存的 SDK 目录。如果缓存命中,就跳过下载步骤;如果缓存未命中,则安装 cmdline-tools、接受许可证、安装指定组件,最后保存缓存。
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up JDK
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 17
- name: Cache Android SDK
uses: actions/cache@v4
with:
path: /opt/android-sdk
key: android-sdk-34-34.0.0
- name: Install SDK
run: |
mkdir -p /opt/android-sdk/cmdline-tools
wget https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip
unzip commandlinetools-linux-11076708_latest.zip -d /opt/android-sdk/cmdline-tools
mv /opt/android-sdk/cmdline-tools/cmdline-tools /opt/android-sdk/cmdline-tools/latest
yes | /opt/android-sdk/cmdline-tools/latest/bin/sdkmanager --licenses
/opt/android-sdk/cmdline-tools/latest/bin/sdkmanager --install "platforms;android-34" "build-tools;34.0.0" "platform-tools"
在上面的 YAML 中,缓存键最好包含 platform 和 build-tools 的版本号。当 SDK 版本升级时,缓存键发生变化,CI 会自动创建新缓存,避免旧版本组件残留。如果项目同时使用 NDK,应把 NDK 版本也纳入缓存键,因为 NDK 体积较大,单独缓存能明显提升恢复速度。
对于 Jenkins 或 GitLab Runner,也可以采用类似思路:先判断本地 SDK 目录是否完整,再决定是否执行下载。判断条件可以检查关键文件是否存在,例如 platforms/android-34/android.jar 和 build-tools/34.0.0/aapt2。只要目录结构和文件完整,就可以直接进入 Gradle 构建阶段。
常见错误与排查方法
最常见的报错之一是许可证未接受,提示内容通常为 You have not accepted the license agreements of the following SDK components。解决方法是执行 yes | sdkmanager --licenses,并在 CI 脚本中将这一步放在安装之前。另一个常见问题是 ANDROID_HOME 和 ANDROID_SDK_ROOT 指向不一致,导致部分工具无法定位 SDK。建议排查时先打印这两个变量的值,确认它们指向同一个目录。
构建过程中还可能出现 Failed to find build tools revision 34.0.0 之类的错误。这通常表示 build-tools 未安装或路径不正确。可以先运行 sdkmanager --list_installed 查看已安装组件,再根据报错版本重新安装。磁盘空间不足也会造成下载或解压失败,尤其是在同时安装多个 system-images 和 NDK 时,建议为 SDK 目录预留至少 20GB 空间。
如果遇到 aapt2 无法执行,可以检查 build-tools 对应的可执行文件是否存在,并确认系统架构是否匹配。Windows 下还要留意路径中是否包含空格或中文字符,虽然新版本工具链对这些场景兼容性已有改善,但使用纯英文无空格路径仍然是最稳妥的选择。
SDK 版本管理的核心并不是安装一次就结束,而是把 SDK 组件视作项目构建契约的一部分。通过命令行脚本锁定版本、统一环境变量、配置镜像缓存,并在 CI 中自动化安装和恢复,可以让 Android 构建环境从个人电脑到服务器保持一致,显著减少由环境差异带来的排查成本。
Android SDK下载版本管理SDK环境配置修改时间:2026-08-30 18:05:55