简介:Android 命令行工具(commandlinetools-linux-13114758-latest.zip)面向 Linux 开发者,适合不想安装完整 Android Studio、又希望通过脚本自动化管理 SDK 组件的场景。压缩包共 108 个文件,大小约 157.13MB;其中 95 个 jar 文件提供核心运行支撑,sdkmanager、avdmanager、apkanalyzer、lint、d8/r8、screenshot2、profgen 等可执行工具分别负责包管理、虚拟设备管理、APK 分析、代码检查与构建编译。目前已有 282 人学习下载,适合熟悉命令行操作的中高级 Android 开发者。借助这套工具链,开发者可通过 sdkmanager 灵活拉取 NDK、模拟器等平台组件,并将其接入自动化构建与持续集成流程,替代传统 IDE 中的图形界面操作;readme、properties 等辅助文件也便于快速完成环境配置与问题排查。工具包内包含 cmdline-tools 目录,集中放置了命令行操作所需的可执行文件与运行库;整体结构紧凑,既保留了 Linux 命令行的工作习惯,又降低了维护多版本 SDK 时的重复劳动,适合需要批量部署和可重复构建的团队或个人使用。
1. 命令行工具包解压之后,才是真正开始
拿到commandlinetools-linux-13114758-latest.zip这个文件名时,容易产生一个错觉:解压完就有一个能用的 Android 构建环境。实际解压后只有一个cmdline-tools目录,里面是bin和lib,敲sdkmanager大概率会报“command not found”,因为环境变量没配、目录没摆对、JDK 版本也可能不对。这个 zip 是 Android SDK 的“安装器”,不是 SDK 本身,它负责把platform-tools、build-tools、platforms;android-XX、system-images等组件拉取到本地。
对一线工程师来说,这个包的价值体现在无人值守的 CI 环境、容器构建镜像、以及不想装完整 Android Studio 的 Linux 开发机上。命令行工具包里的sdkmanager可以做静默安装和版本锁定,avdmanager能创建模拟器镜像,apkanalyzer能直接读取 APK 的 manifest 和资源信息。全文围绕这个工具包在 Linux 上的落地,把目录结构、环境变量、常用组件、隐藏参数和实际坑位一次说清。
2. 理解 commandlinetools 的目录结构与版本识别
2.1 zip 里到底有什么:一个自举的包管理器
解压commandlinetools-linux-13114758-latest.zip后,得到的是:
cmdline-tools/ ├── bin/ │ ├── avdmanager │ ├── lint │ ├── profgen │ ├── retrace │ ├── screenshot2 │ └── sdkmanager └── lib/ ├── dalvik-dx.jar ├── dvlib.jar ├── layoutlib.jar ├── repository.xml └── sdk-common.jarbin下的工具本质是 shell 脚本,真正的逻辑在lib里的 Java 代码中。最核心的依赖是本地 JDK,脚本开头会通过JAVA_HOME或PATH查找java,找不到就直接退出。
repository.xml这个文件容易忽略,它缓存了 SDK 组件的元数据(版本号、依赖关系、下载地址),sdkmanager检查更新和解析依赖时都需要它。如果这个文件损坏,常见的表现是sdkmanager --list卡住或报 XML 解析错误,删除后重跑命令会自动重建。
2.2 为什么必须放到 cmdline-tools/latest 目录
commandlinetools包自 2022 年起引入了“latest”目录约定。下载后默认结构是cmdline-tools/,如果直接配置 PATH,sdkmanager 会提示目录层级不正确。标准做法是把它移到 SDK 根目录下的cmdline-tools/latest:
export ANDROID_HOME=$HOME/android-sdk mkdir -p $ANDROID_HOME/cmdline-tools unzip commandlinetools-linux-13114758-latest.zip -d /tmp/cmdline-tools mv /tmp/cmdline-tools/cmdline-tools $ANDROID_HOME/cmdline-tools/latest移动后再用find $ANDROID_HOME -name sdkmanager确认路径。sdkmanager依赖ANDROID_HOME环境变量定位 SDK 根目录,然后从cmdline-tools/latest/lib加载运行库。目录层级不对会触发一个很隐蔽的错误——命令能执行,但下载的组件被写到了错误位置。
2.3 版本号 13114758 能告诉我们什么
13114758不是传统语义化版本号,而是 Google 内部构建系统的构建序列号,每个 cmdline-tools 发布版本都对应唯一的构建号。它对应的发布渠道(stable/beta/canary)可以从repository.xml里的<tool>节点确认,也可以直接跑:
$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --version输出会是类似13.0.0这样的版本。这个信息在 CI 里很重要,因为团队经常会问“当前用的 SDK 工具到底是不是稳定版”。构建号还能辅助判断和 Android Studio 的兼容性——Studio 自带的 cmdline-tools 版本如果低于项目期望值,Gradle 会警告。
提示:实际下载时文件名可能写成
commandlinetools-linux-13114758_latest.zip(下划线分隔),解压内容一致,不影响后续操作。
3. 用 sdkmanager 在 Linux 上安装 Android SDK 组件
3.1 最小可用安装:三条命令跑通
sdkmanager 是命令行工具包里的安装主力,职责是下载、安装、卸载和列出 SDK 组件。最小安装流程如下:
export ANDROID_HOME=$HOME/android-sdk export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin # 接收所有 license yes | sdkmanager --licenses # 安装最基础的组件 sdkmanager --install "platform-tools" "platforms;android-34" "build-tools;34.0.0"第一条命令里的yes管道用于自动应答 license 协议,否则会交互式卡在y/N提示。第二条命令的包名有固定格式:platform-tools没有版本号(永远跟随最新),platforms和build-tools必须用分号分隔并带上 API Level 或构建工具版本。
安装完成后建议验证目录:
ls $ANDROID_HOME/platforms/android-34/android.jar ls $ANDROID_HOME/build-tools/34.0.0/aapt2 ls $ANDROID_HOME/platform-tools/adb这能确认android.jar(编译用)、aapt2(资源打包)和adb(调试)都真实存在,而不只是 sdkmanager 认为安装成功。
3.2 组件选型:一套可持续维护的包名清单
实际项目里常用的 SDK 组件远不止三个。下表是调试时高频使用的包名和用途:
| sdkmanager 包名 | 安装内容 | 典型用途 |
|---|---|---|
platform-tools | adb、fastboot、e2fsdroid 等 | 设备连接、刷机 |
build-tools;34.0.0 | aapt2、aidl、zipalign、apksigner | 构建、签名、对齐 |
platforms;android-34 | android.jar、build.prop | 编译时引用 API |
system-images;android-34;google_apis;x86_64 | 完整系统镜像 | 创建模拟器 |
ndk;26.1.10909125 | NDK 工具链 | 编译 C/C++ 代码 |
cmake;3.22.1 | CMake 与 ninja | 驱动 NDK 构建 |
emulator | 模拟器二进制 | 运行 AVD |
日常开发机的标准组合是 platform-tools + platforms + build-tools,加上对应 API Level 的 system image。只有 NDK 需求才装最后一个。注意包名里的版本号精确到补丁级,build-tools;34这种写法是无效的,必须写出完整版本。半年前踩过这个坑,CI 日志里报Failed to find package build-tools;34,当时查了半天才发现少写了.0.0。
3.3 无人值守安装:怎么做到完全静默
在 CI 或容器构建环境里,交互式输入是灾难。sdkmanager 支持完全静默模式:
sdkmanager --install "platforms;android-34" "build-tools;34.0.0" --channel=0 --sdk_root=$ANDROID_HOME echo "y" | sdkmanager --licenses --sdk_root=$ANDROID_HOME--channel=0表示只从稳定版渠道安装,这个参数在团队统一版本时很关键。--sdk_root显式指定根目录,避免环境变量传递不一致时把组件装错地方。
锁版本的做法是把包名写死在构建脚本里,并且用 checksum 校验下载:
echo "9a00694c86f94e28d42b5b6f9a0c3a9b" | sdkmanager --install "platforms;android-34" --sdk_root=$ANDROID_HOME如果安装过程中 license 接收失败,日志会出现Failed to install packages的提示,通常是因为 license 文件目录权限不对。先执行chmod -R u+w $ANDROID_HOME/licenses再重试即可。
3.4 官方源之外的问题定位思路
sdkmanager 默认从 Google 官方仓库下载,网络不佳时表现为“解析元数据超时”或“download interrupted: Connection reset”。排查时抓两个位置:一是lib/repository.xml的更新时间,二是 sdkmanager 的日志输出。常用诊断命令:
sdkmanager --list --verbose 2>&1 | tail -50 sdkmanager --list_installed--list_installed能列出当前已装的组件,用来对比 CI 和本地环境差异。--verbose能显示 HTTP 请求细节,包括实际的下载 URL,方便确认是否走了代理。如果检查发现本地与 CI 组件列表不一致,对齐版本后一般能解决“本地编得过、CI 编不过”的问题。
4. 用 avdmanager 和 apkanalyzer 完成模拟器与 APK 分析
4.1 创建模拟器:系统镜像与设备定义的匹配逻辑
avdmanager 是创建和管理 Android 虚拟设备(AVD)的命令行入口。大致流程是写system image的包名,让 sdkmanager 装好镜像,然后 avdmanager 创建 AVD 实例。
sdkmanager --install "system-images;android-34;google_apis;x86_64" avdmanager create avd -n ci_test -k "system-images;android-34;google_apis;x86_64" -d pixel_5 --force-d pixel_5指定设备定义,控制屏幕分辨率、内存参数和可用按键。--force在 AVD 名已存在时覆盖而不提示。创建好后用:
avdmanager list avd确认 AVD 出现在列表。模拟器实际启动由emulator组件提供,而 cmdline-tools 包里并没有带emulator,需要单独安装。很多新手会在这时去编辑config.ini来调 memory,但标准做法是先查设备定义:
avdmanager list device | grep -A 10 "pixel_5"4.2 命令行里跑模拟器的两个关键技巧
模拟器的-no-window和-no-audio参数是 CI 环境里最常见的组合:
$ANDROID_HOME/emulator/emulator -avd ci_test -no-window -no-audio -no-boot-anim -gpu swiftshader_indirect启动后要轮询等待系统完全起来,常见做法是循环检测sys.boot_completed:
adb wait-for-device until adb shell getprop sys.boot_completed 2>/dev/null | grep -q 1; do sleep 5 doneswiftshader_indirect用软件渲染 GPU,避免物理 GPU 带来的兼容性问题。-no-boot-anim能减少启动时间约 10~15 秒。执行完测试后建议立刻关闭模拟器:
adb emu kill4.3 apkanalyzer:不写代码直接读 APK
apkanalyzer 读取 APK 的 manifest、资源和 dex 信息的能力,在排查“包名写没写对”“versionCode 对不对”这类问题时特别有用。基础命令是:
apkanalyzer manifest print app-release.apk这个命令会输出完整 AndroidManifest.xml,包括权限列表、四大组件和应用 ID。只看某个属性也有专门参数:
apkanalyzer manifest application-id app-release.apk apkanalyzer manifest version-name app-release.apk apkanalyzer apk summary app-release.apkapk summary返回 APK 大小、minSdk、targetSdk 三项核心信息,适合快速验证构建产物是否符合预期。需要确认某个 Activity 是否存在时,用manifest activities结合 grep 即可。
4.4 lint 的实用跑法:跳过 Gradle 直接命令行执行
lint 独立于 Gradle 运行,可以直接扫描源码目录,输出问题报告。工作量较小的检查这样跑:
lint --check GradleDependency --severity warning app/src/main--check指定检查规则,--severity warning控制最低输出级别为 warning。想要 HTML 报告方便在浏览器里看:
lint --html /tmp/lint-report.html app/src/mainlint 的这些功能在 CI 里可以作为 Gradle lint 任务的轻量替代,先用命令行快速扫一遍,再决定是否进入完整构建流程。比起改build.gradle里的lintOptions,这种临时用法更适合排查问题。
5. 环境隔离、复杂变量组合与高阶排查技巧
5.1 多版本共存:让开发者机器里的 SDK 和 CI 不必一致
同一台机器维护两个 Android SDK 根目录是常见需求,比如一个给内部项目用稳定版,另一个给新项目试 Preview API。命令行工具包的--sdk_root参数可以让同一套 cmdline-tools 操作不同的 SDK 目录:
sdkmanager --sdk_root=/opt/android-sdk-stable --install "platforms;android-34" sdkmanager --sdk_root=/opt/android-sdk-preview --install "platforms;android-34" "platforms;android-35"两套 SDK 并存时,ANDROID_HOME只能指向其中一个,但如果某个构建脚本内部显式写死了ANDROID_HOME,必须确认它是从环境变量读的还是硬编码的。硬编码场景,建议用--sdk_root显式覆盖,避免构建脚本之间相互污染。
5.2 一组可复制的高阶参数组合
把前面所有技巧拼在一起,构成一个可在 Linux 服务器上直接使用的完整脚本块:
export ANDROID_HOME=$HOME/android-sdk export PATH=$ANDROID_HOME/cmdline-tools/latest/bin:$PATH # 安装全部所需组件,--channel=0 锁稳定版 sdkmanager --channel=0 \ --install "platform-tools" \ "platforms;android-34" \ "build-tools;34.0.0" \ "system-images;android-34;google_apis;x86_64" # 验证 sdkmanager 自带工具版本 sdkmanager --version # 创建 AVD 并冷启动 avdmanager create avd -n ci_test -k "system-images;android-34;google_apis;x86_64" -d pixel_5 --force $ANDROID_HOME/emulator/emulator -avd ci_test -no-window -no-audio -no-boot-anim -gpu swiftshader_indirect & adb wait-for-device # 等 sys.boot_completed until adb shell getprop sys.boot_completed 2>/dev/null | grep -q 1; do sleep 5; done执行时如果卡在某一个环节,优先看环境变量:
env | grep -E "ANDROID|JAVA"原因是脚本多次 export 后,可能覆盖了系统原有的ANDROID_SDK_ROOT。sdkmanager 读取优先级是--sdk_root参数大于ANDROID_SDK_ROOT大于ANDROID_HOME,在不传参时两个环境变量若指向不同目录,行为会变得很难预期。
5.3 日志、退出码与半成品组件残留
sdkmanager 的退出码设计并不复杂:0 表示成功,非 0 表示失败。但失败后不一定回滚,可能出现组件半安装状态,比如platforms/android-34目录存在但android.jar缺失。验证干净环境的方法:
sdkmanager --list_installed | grep "android-34" test -f $ANDROID_HOME/platforms/android-34/android.jar && echo "OK"如果android.jar缺失,直接重装该组件即可:sdkmanager --install "platforms;android-34"。卸载组件时要注意依赖关系,比如先卸载了platform-tools,adb 相关脚本会直接失效,但 sdkmanager 本身不受影响。
提示:遇到“java.lang.UnsupportedClassVersionError”时,多半是 JDK 版本过低,cmdline-tools 需要 JDK 17 及以上。执行
java -version确认版本,必要时安装新版 OpenJDK 后重新设置JAVA_HOME。
5.4 版本锁定:在 CI 中固定 commandlinetools 版本
团队协作中,commandlinetools 本身的版本漂移比 SDK 组件版本漂移更隐蔽。构建机上普遍用-latest文件名下载,一旦仓库发布了新构建号,下次 CI 拉取就会静默换版本。锁定的做法是保存完整构建号:
# 构建脚本开头记录 echo "cmdline-tools version: $(sdkmanager --version)"配合repository.xml的缓存到制品仓库,能让构建在离线环境也不受影响。先把cmdline-tools的 tar 包推送到内网,再把lib/repository.xml一并缓存,之后所有安装操作都走内网源。这种做法在离线或半离线项目里是稳定输出来源的核心手段。
本文还有配套的精品资源,点击获取