简介Android SDK Build-Tools 29.0.2 是面向 Android 应用开发者、构建工程师及移动端学习者的核心构建工具集对应 Android 10API 29版本用于完成资源编译、字节码转换、代码混淆优化、APK 对齐与签名等构建环节。压缩包共 173 个文件约 37.16MB以 85 个 C/C 头文件、24 个 so 动态库、17 个 rsh 脚本、13 个 exe 可执行程序、7 个 jar 包及 6 个 dll 为主另含 bat 批处理、bc 字节码与 a 静态库等覆盖 AAPT2、d8/dx、R8、Zipalign、apksigner 等工具的运行依赖。已有 1372 人学习下载适合需要配置本地 SDK 环境、排查构建报错或研究打包流程的开发者参考。掌握其中各工具的用途与调用方式有助于提升应用编译效率、减小包体并保障签名安全。1. build-tools.29.0.2.zip一个让老项目重新跑起来的构建工具包如果你手里有一个两三年前甚至更早的 Android 项目某天突然需要重新编译打包大概率会在 Gradle 同步阶段撞上这样一条报错Failed to find Build Tools revision 29.0.2。这不是代码写错了而是构建环境里缺了一个叫build-tools.29.0.2.zip的东西。它本质上是 Android SDK 构建工具链的一个版本压缩包解压后提供 aapt2、d8、zipalign、apksigner 等命令行工具负责把资源编译、字节码转换、签名对齐这一整条流水线跑通。29.0.2 这个版本号对应的是 Android 10 时代的构建工具很多存量项目、老教程、第三方 SDK 的示例工程都锁定了它。这篇文章面向的是需要复现老项目构建环境、或者被这个报错卡住的开发者从它是什么、怎么装、参数怎么配、坑在哪一步步讲清楚。2. 先搞清楚 build-tools 29.0.2 到底装了什么2.1 构建工具包的目录结构与核心二进制把build-tools.29.0.2.zip解压后你会看到一个以版本号命名的目录里面通常包含这些关键文件文件名作用是否常被直接调用aapt2资源编译与链接处理 XML、图片、字符串是AGP 内部调用aapt旧版资源打包工具部分老脚本仍依赖偶尔d8将 Java 字节码转为 DEX是AGP 内部调用dx旧版 DEX 转换工具29.0.2 仍保留老项目可能引用zipalign对 APK 做 4 字节对齐优化是打包后手动或自动执行apksigner对 APK 进行签名与签名校验是发布流程必用lib64 目录存放 d8、aapt2 等依赖的本地库否自动加载这个目录的路径通常被配置在local.properties或环境变量ANDROID_HOME下Gradle 通过buildToolsVersion 29.0.2去$ANDROID_HOME/build-tools/29.0.2/查找。如果目录不存在或版本号对不上就会抛出前面说的那个错误。2.2 为什么老项目偏偏锁定 29.0.2不是所有项目都需要这个版本但以下几类情况会强制要求第一项目根目录的build.gradle里写了buildToolsVersion 29.0.2而你的 SDK 里只装了 30.x 或 34.x。Gradle 不会自动降级它只认这个字符串。第二某些第三方 SDK 的aar包里带了预编译脚本脚本里硬编码了aapt2的路径指向 29.0.2 的目录。你换高版本脚本找不到文件直接失败。第三CI 流水线的 Docker 镜像里预装的 SDK 只包含特定版本为了和线上构建产物保持一致本地也必须用同一个版本否则签名后的 APK 哈希值可能不同。提示不要盲目把buildToolsVersion改成你现有的高版本。高版本 aapt2 对某些老资源文件的容错性更差可能引入新的编译错误。先确认项目是否真的能跑在高版本上再决定是否升级。2.3 手动安装 build-tools 29.0.2 的两种路径路径一通过 SDK Manager 命令行安装。这是最干净的方式前提是你的网络能访问 SDK 仓库。# 假设 ANDROID_HOME 已配置sdkmanager 在 cmdline-tools 下 sdkmanager build-tools;29.0.2 # 安装完成后验证目录是否存在 ls $ANDROID_HOME/build-tools/29.0.2/ # 应看到 aapt2、d8、zipalign、apksigner 等文件逻辑说明sdkmanager会从官方仓库拉取对应版本的 zip 包并解压到build-tools/29.0.2/。参数build-tools;29.0.2里的分号是固定格式不能写成空格或斜杠。如果提示Warning: Failed to find package说明当前 SDK 源里没有这个版本需要检查sdkmanager --list的输出。路径二手动解压 zip 包。当你已经拿到build-tools.29.0.2.zip文件或者内网仓库只提供离线包时使用。# 创建目标目录 mkdir -p $ANDROID_HOME/build-tools/29.0.2 # 解压 zip 到目标目录注意 zip 内可能有一层顶层文件夹 unzip build-tools.29.0.2.zip -d /tmp/bt29 # 查看解压后的结构确认文件层级 ls /tmp/bt29/ # 如果输出是 android-10/ 这样的目录需要把里面的内容移出来 mv /tmp/bt29/*/* $ANDROID_HOME/build-tools/29.0.2/ # 赋予可执行权限Linux/macOS 下必须做 chmod x $ANDROID_HOME/build-tools/29.0.2/*逻辑说明手动解压最容易翻车的地方是目录层级。有些 zip 包解压后多一层android-10或29.0.2文件夹直接放进去会导致 Gradle 找不到aapt2。必须确保$ANDROID_HOME/build-tools/29.0.2/aapt2这个路径直接存在。参数-d指定解压目标chmod x在 Windows 上不需要但在 macOS 和 Linux 上漏掉会导致Permission denied。3. 在 Gradle 项目里正确引用 29.0.2 并跑通构建3.1 模块级 build.gradle 的配置写法打开你的 app 模块或 library 模块的build.gradle找到android闭包android { compileSdkVersion 29 buildToolsVersion 29.0.2 // 必须与已安装目录名完全一致 defaultConfig { applicationId com.example.legacyapp minSdkVersion 21 targetSdkVersion 29 versionCode 1 versionName 1.0 } // 如果项目里有自定义 aapt2 路径的需求可以这样指定 // aaptOptions { // additionalParameters --no-version-vectors // } }逻辑说明buildToolsVersion的值是一个字符串Gradle 会拿它去$ANDROID_HOME/build-tools/下匹配同名目录。如果写成29.0.2但目录名是29.0.2-rc1就会失败。compileSdkVersion和targetSdkVersion不强制等于 29但建议保持一致避免资源编译时的 API 级别冲突。参数说明minSdkVersion 21是 29.0.2 构建工具能支持的最低 API 级别之一再低会缺少某些 DEX 优化特性。aaptOptions里的additionalParameters是可选的高级参数老项目里常见--no-version-vectors用于关闭矢量图版本控制减少资源冲突。3.2 local.properties 与 ANDROID_HOME 的优先级Gradle 查找 SDK 路径的顺序是local.properties里的sdk.dir 环境变量ANDROID_HOME 环境变量ANDROID_SDK_ROOT。如果你手动解压了 build-tools 但 Gradle 还是报找不到先检查local.properties# local.properties 文件内容示例 sdk.dir/Users/yourname/Library/Android/sdk # Windows 下写法sdk.dirC\:\\Android\\sdk逻辑说明这个文件通常不提交到版本控制由开发者本地生成。如果sdk.dir指向的路径下没有build-tools/29.0.2/Gradle 就会报错。注意 Windows 路径里的反斜杠需要转义冒号也要转义否则解析失败。注意有些 IDE 会自动生成local.properties但如果你从旧机器拷贝项目这个文件可能还指向旧机器的路径。手动改成本机实际路径即可。3.3 用命令行验证构建工具是否可用在跑完整构建之前先单独验证aapt2和d8能否执行# 进入 build-tools 目录 cd $ANDROID_HOME/build-tools/29.0.2 # 查看 aapt2 版本正常应输出版本号 ./aapt2 version # 输出示例Android Asset Packaging Tool (aapt) 2.19-... # 查看 d8 是否可执行 ./d8 --version # 输出示例D8 1.6.0 # 检查 zipalign 帮助信息 ./zipalign -h逻辑说明这三个命令能跑通说明二进制文件完整且权限正确。如果aapt2 version报No such file or directory可能是解压时文件损坏或者系统缺少 32 位兼容库老版本 aapt2 在 64 位 Linux 上可能需要lib32z1。d8 --version的输出格式在不同小版本间略有差异只要不报错即可。参数说明aapt2 version不带其他参数直接输出版本字符串。d8 --version同理。zipalign -h会打印用法说明如果输出为空或报错说明二进制有问题。4. 避坑build-tools 29.0.2 最常见的五个翻车现场4.1 现象Gradle 报Failed to find Build Tools revision 29.0.2但目录明明存在原因目录名不完全匹配。比如你解压后目录叫29.0.2但build.gradle里写的是29.0.2后面多了一个空格或者目录实际叫android-29.0.2。Gradle 是字符串精确匹配差一个字符都不行。解决用ls $ANDROID_HOME/build-tools/列出所有目录名复制粘贴到build.gradle里。同时检查build.gradle里有没有不可见字符。4.2 现象aapt2 执行时报error while loading shared libraries: libc.so.1原因29.0.2 的 aapt2 是动态链接的依赖系统里的libc共享库。较新的 Linux 发行版默认没有这个库或者版本不兼容。解决安装兼容库。在 Ubuntu/Debian 上执行sudo apt-get install libc1在 CentOS/RHEL 上执行sudo yum install libcxx。如果还不行从更高版本的 build-tools 里拷贝lib64/libc.so到 29.0.2 的lib64目录下但要注意 ABI 兼容性。4.3 现象构建成功但 APK 安装到 Android 10 以上设备闪退原因zipalign没有执行或者执行时用了错误的对齐参数。29.0.2 的zipalign默认按 4 字节对齐但某些老脚本里写的是-p参数按页对齐导致 APK 在 Android 10 上校验失败。解决检查打包脚本里的zipalign命令。正确的做法是zipalign -v 4 input.apk output.apk-v输出详细日志4是对齐字节数。不要用-p除非你明确知道目标设备的页大小。4.4 现象d8 转换 DEX 时内存溢出报java.lang.OutOfMemoryError原因29.0.2 的 d8 默认堆内存较小大型项目方法数超过 10 万容易撑爆。Gradle 虽然会传-J-Xmx参数但老版本 AGP 可能没传够。解决在gradle.properties里加大内存# gradle.properties org.gradle.jvmargs-Xmx4096m -XX:MaxPermSize512m逻辑说明-Xmx4096m给 Gradle 守护进程 4GB 堆内存d8 作为子进程会继承一部分。如果还不行在build.gradle里显式给 d8 传参android { dexOptions { javaMaxHeapSize 4g } }参数说明javaMaxHeapSize只对旧版 dx/d8 生效单位可以是g或m。注意这个配置在 AGP 4.0 以上已被废弃但 29.0.2 对应的 AGP 版本通常还在 3.5 左右所以仍然可用。4.5 现象手动解压后 Windows 上 Gradle 报Access is denied原因Windows 不会自动给解压出来的文件加可执行权限而且某些杀毒软件会锁定aapt2.exe。解决右键aapt2.exe和d8.bat确认没有“阻止”标记。如果杀毒软件拦截把$ANDROID_HOME/build-tools/29.0.2/加入白名单。另外Windows 下zipalign.exe和apksigner.bat需要区分调用Gradle 会自动处理但手动执行时要用.bat后缀。5. 进阶把 29.0.2 构建工具固化到 CI 与多版本共存5.1 在 CI 脚本里静默安装指定版本如果你的 CI 环境每次都是干净容器可以用sdkmanager静默安装避免手动解压的路径问题#!/bin/bash set -e # 接受 SDK 许可避免交互式确认 yes | sdkmanager --licenses # 安装 build-tools 29.0.2 和对应平台 sdkmanager build-tools;29.0.2 platforms;android-29 # 验证安装 if [ ! -d $ANDROID_HOME/build-tools/29.0.2 ]; then echo build-tools 29.0.2 安装失败 exit 1 fi # 后续执行 Gradle 构建 ./gradlew assembleRelease逻辑说明yes | sdkmanager --licenses自动接受所有许可协议适合无人值守环境。set -e让脚本在任何命令失败时立即退出避免带着错误继续跑。sdkmanager安装的目录结构是标准的不会出现手动解压的层级问题。参数说明build-tools;29.0.2和platforms;android-29可以写在同一行用空格分隔。如果 CI 网络受限可以提前把 zip 包放到内网文件服务器用wget下载后手动解压但要注意校验文件完整性。5.2 多版本 build-tools 共存时的切换策略一台机器上同时装 29.0.2、30.0.3、34.0.0 是常态。Gradle 根据每个模块的buildToolsVersion自动选择不需要手动切换。但如果你用命令行直接调aapt2就要注意 PATH 里默认指向哪个版本。# 查看当前 PATH 里的 aapt2 指向 which aapt2 # 如果输出 /usr/local/bin/aapt2可能是软链接 # 显式使用 29.0.2 的 aapt2 $ANDROID_HOME/build-tools/29.0.2/aapt2 version # 在脚本里用变量固定版本避免歧义 BT_VERSION29.0.2 AAPT2$ANDROID_HOME/build-tools/$BT_VERSION/aapt2 $AAPT2 compile --dir res -o compiled.flata逻辑说明which aapt2帮你确认默认命令来自哪里。在自动化脚本里永远用绝对路径调用构建工具不要依赖 PATH。aapt2 compile是资源编译的第一步--dir res指定资源目录-o指定输出文件。这个命令在 29.0.2 和更高版本间基本兼容但输出格式可能有细微差异。参数说明BT_VERSION是自定义变量方便后续统一修改。compiled.flata是编译后的资源压缩包后续用aapt2 link链接成 APK 资源。如果项目里有多个模块每个模块的buildToolsVersion可以不同Gradle 会分别处理。5.3 验证构建产物是否真的用了 29.0.2构建完成后怎么确认 APK 是用 29.0.2 的工具链打出来的可以检查 APK 里的META-INF目录和资源表版本# 用 29.0.2 的 aapt2 dump 资源表 $ANDROID_HOME/build-tools/29.0.2/aapt2 dump resources app-release.apk | head -20 # 查看 APK 的 zip 对齐情况 $ANDROID_HOME/build-tools/29.0.2/zipalign -c -v 4 app-release.apk # 输出中会显示每个文件的偏移量和对齐验证结果逻辑说明aapt2 dump resources会打印资源表的头部信息包括编译时使用的 aapt2 版本号。zipalign -c是检查模式不修改文件只验证对齐。-v输出详细列表4是对齐字节数。如果输出最后显示Verification succesful说明对齐正确。参数说明head -20只取前 20 行避免输出过长。-c表示 check-v表示 verbose。这两个参数组合在排查 APK 安装失败时非常有用。5.4 一个我踩过的坑不要混用不同版本的 apksigner有一次为了图快用 34.0.0 的apksigner给 29.0.2 构建出来的 APK 签名结果在 Android 9 设备上安装失败报INSTALL_PARSE_FAILED_NO_CERTIFICATES。原因是高版本apksigner默认启用了 v2/v3 签名方案而老设备对 v3 支持不完整。后来换回 29.0.2 自带的apksigner问题消失。血泪经验构建工具链的版本要尽量统一。aapt2、d8、zipalign、apksigner最好来自同一个 build-tools 目录。如果必须混用先用apksigner verify -v检查签名方案确认目标设备支持。# 用 29.0.2 的 apksigner 签名并指定只启用 v1 和 v2 $ANDROID_HOME/build-tools/29.0.2/apksigner sign \ --ks my-release-key.jks \ --ks-key-alias myalias \ --v1-signing-enabled true \ --v2-signing-enabled true \ --v3-signing-enabled false \ --out app-signed.apk app-unsigned.apk逻辑说明--v1-signing-enabled true启用 JAR 签名兼容 Android 7 以下。--v2-signing-enabled true启用 APK Signature Scheme v2兼容 Android 7 到 9。--v3-signing-enabled false关闭 v3避免老设备解析失败。--ks指定密钥库--ks-key-alias指定别名--out指定输出文件。参数说明如果你的minSdkVersion是 21v1 和 v2 同时开启是最稳妥的。v3 只在targetSdkVersion28 以上且设备支持时才需要。签名完成后用apksigner verify -v app-signed.apk查看实际启用的方案。希望帮到你。本文还有配套的精品资源点击获取