ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

不装Android Studio:用commandlinetools搭建Linux构建环境指南

不装Android Studio:用commandlinetools搭建Linux构建环境指南 简介资源为面向 Linux 开发者的 Android 命令行工具压缩包适合不希望安装完整 Android Studio、希望通过脚本化方式管理 SDK 组件的中高级开发者。压缩包内含 108 个文件主要类型包括 95 个 jar 工具库如 r8、d8、lint、apkanalyzer 等、sdkmanager、avdmanager、screenshot2 等可执行脚本以及配置属性和说明文档。包体积 157.13MB核心是 cmdline-tools 目录解压并配置环境变量后即可通过 sdkmanager 下载、更新 NDK、模拟器及其他平台组件。资源已有 284 人学习。通过该工具包开发者能获得轻量级的 SDK 管理入口在自动化构建和持续集成流程中快速管理 Android 开发组件是 Linux 环境下提升开发可控性与效率的实用选择。1. 一个 zip 装出整套 Android 构建环境commandlinetools 到底管什么我刚拿到一台干净的 Ubuntu 服务器时第一件事不是装 Android Studio而是下载这个 Android 命令行工具包commandlinetools-linux-13114758-latest.zip。它不占几个 G解压后是一组 shell 脚本和 jar 包却能干完“拉 SDK、装 build-tools、建模拟器、分析 APK”这一整套脏活。很多人在 Android Studio 里点半天鼠标才能完成的事在这套工具里就是几条命令的事。这个包管的是 Android SDK 的入口层sdkmanager 负责下载和管理各个 SDK 组件avdmanager 负责创建虚拟设备apkanalyzer 负责拆 APK。它解决的核心问题是“没有图形界面、不装全家桶照样能把 Android 工程跑起来”。尤其适合三类人靠 CI 出包的运维和脚本党、在远程 Linux 上调试的开发者以及被 Android Studio 下载慢折磨到想换方案的人。需要先说明白这不是一个“能编译 APK 的编译器”本身不带 platform 和 build-tools它是个工具入口。你拿到这个 zip 只是开始后面要通过它把真正的 SDK 组件一个个装进来。整条链路跑通之后你会发现自己对 Android 工程的理解比天天点 IDE 的人清楚得多因为每一步都摆在你面前。2. 拆包看货解压后的目录里藏着哪几个命令与 latest 目录约定2.1 先解压开看bin/ 下到底有哪些可执行文件拿到 zip 的第一步永远是先解开看一眼别急着配环境变量。我一般会解压到一个临时目录然后再决定怎么摆放。用 unzip 直接解压再用 find 把前几层文件列出来。mkdir -p ~/android-sdk unzip -q commandlinetools-linux-13114758-latest.zip -d ~/android-sdk find ~/android-sdk -maxdepth 3 -type f | sort这里的-q是安静模式解压过程不刷屏-d指定解压目标目录。解压后你会看到顶层是一个cmdline-tools文件夹里面才是真正的内容。find列出文件后重点关注cmdline-tools/bin/下的几个可执行脚本sdkmanager、avdmanager、apkanalyzer、lint、retrace外加一些 .bat 批处理那是给 Windows 用的和 .jar 包。这个 bin 目录才是整套工具的精华所在。sdkmanager 是 SDK 组件管理器下载和卸载都靠它avdmanager 管虚拟设备apkanalyzer 用来分析 APK 包lint 做静态检查。很多人到处找独立的 aapt2、adb 下载包其实正确的姿势是先装好这套命令行工具再用 sdkmanager 把那些组件拉下来版本和依赖才不容易乱。2.2 latest 目录不是装样子sdkmanager 的位置约定这里有个新手几乎必踩的坑sdkmanager 对自身所在目录有严格要求不是放在哪都能跑。它要求工具必须位于$ANDROID_HOME/cmdline-tools/latest/bin这样的层级里也就是cmdline-tools下必须套一个latest子目录。如果你直接把解压出来的cmdline-tools原封不动放到 SDK 根目录运行sdkmanager --version大概率会报错或者行为诡异。正确的摆放方式是这样的cd ~/android-sdk mkdir -p cmdline-tools/latest mv cmdline-tools/bin cmdline-tools/lib cmdline-tools/NOTICE.txt cmdline-tools/source.properties cmdline-tools/latest/这里把原来cmdline-tools目录里的内容全部挪进latest/子目录最终结构是~/android-sdk/cmdline-tools/latest/bin/sdkmanager。source.properties这个文件里写的Pkg.Revision就是构建版本号 13114758你可以用它核对当前工具版本。为什么官方要这么设计因为以后你升级工具时新版本解压后可以替换latest目录里的内容或者并行放一个带版本号的目录再通过latest做软链切换。常见的做法是保留cmdline-tools/11.0.0、cmdline-tools/12.0.0这样的旧版本出问题时能快速回滚而不是覆盖到不可恢复。2.3 构建号 13114758、latest 与 API Level 到底是什么关系每次下载这个 zip文件名里都会带一串数字这串 13114758 是构建号build number它只代表这一版 Android 命令行工具自身的迭代版本跟 Android 系统的 API Level比如 34、35完全是两套编号。同一个构建号可以下载所有 API Level 的 platform 和 build-tools两个维度不互相依赖。还有一个容易误解的点文件名里的latest是下载页面用来区分“当前推荐版”的命名方式不代表这个 zip 解压后会自己更新。你装好之后要升级工具靠的是sdkmanager --update命令而不是重新下载一遍latest.zip。我见过同事每次都重新下 zip 覆盖安装结果越覆盖越乱。那这个包和 Android Studio 是什么关系Android Studio 安装时的 SDK 组件就是通过这套命令行工具拉取的只是把过程封装到了图形界面里。如果你已经装了 Android Studio它自带的 SDK 里通常也有 cmdline-tools 目录。但对 CI、服务器、无头环境来说命令行工具包是更轻量的唯一合理入口。它能做到 Android Studio 能做的大部分 SDK 管理事情却不带几百 MB 的 IDE 开销。3. 在 Linux 上从零装好 commandlinetoolsJDK、解压、路径与第一个实例3.1 前置条件JDK 版本和系统架构先搞清楚动手之前先跑两条命令否则后面报了错再回头排查就慢了。grumpy 的经验是这套工具对 Java 版本非常敏感新构建号基本都要求 JDK 17 起步装个 OpenJDK 17 是最省心的选择。java -version uname -m第一条看 JDK 版本第二条看 CPU 架构。uname -m输出x86_64就是 64 位 x86aarch64是 ARM 64这两个架构官方都有对应可用版本但 32 位系统直接放弃新版工具早就不支持了。如果java -version报找不到命令先装 OpenJDKDebian/Ubuntu 上一般apt install openjdk-17-jdk-headlessCentOS/RHEL 用dnf install java-17-openjdk-devel。无头环境装 headless 版就够不需要图形模块。有人问能不能用 JDK 11 或 JDK 8低版本的构建号配 JDK 8 是能跑的但 13114758 这种新包配老 JDK 会直接报UnsupportedClassVersionError现象就是 Java 启动类失败看起来像工具坏了其实是版本不匹配。所以别折腾直接上 17。还有个容易忽略的点如果你机器上有多个 Java 版本java命令指向的可能不是你以为的那个版本用update-alternatives --config java或者显式把 JDK 17 的 bin 目录放最前面。3.2 把 zip 放到哪、解压到哪、目录结构怎么摆目录规划很关键因为后面所有路径都会跟它挂钩。个人开发机我一般放~/android-sdk团队共用服务器放/opt/android-sdk。选好根目录后先建目录再解压到临时位置最后挪成latest结构。这个“先解压再挪”的顺序可以避免直接解压后目录层级不对的问题。export ANDROID_HOME~/android-sdk export ANDROID_SDK_ROOT$ANDROID_HOME mkdir -p $ANDROID_HOME unzip -q commandlinetools-linux-13114758-latest.zip -d /tmp/cmdtools-unzip mkdir -p $ANDROID_HOME/cmdline-tools/latest mv /tmp/cmdtools-unzip/cmdline-tools/* $ANDROID_HOME/cmdline-tools/latest/ rm -rf /tmp/cmdtools-unzip这里设置了ANDROID_HOME和ANDROID_SDK_ROOT两个变量ANDROID_HOME是主路径ANDROID_SDK_ROOT是为了兼容一些老工具和旧项目脚本两个都设成同一个路径最省事。解压到/tmp再移动是为了让目标目录干净最后删除临时目录。注意mv /tmp/cmdtools-unzip/cmdline-tools/*里的通配符会把所有内容挪进 latest 子目录最终结构是~/android-sdk/cmdline-tools/latest/bin。有个细节别把整个cmdline-tools目录直接移进去那会变成cmdline-tools/latest/cmdline-tools/bin多套一层导致脚本找不到自身位置。3.3 环境变量与 PATHsdkmanager 如何被找到目录摆好之后要让系统能找到这些命令。把下面几行写进~/.bashrc或~/.zshrcPATH 里要同时包含 cmdline-tools 的 bin 和 platform-tools后者是装完 adb 之后才有用的但可以先把路径写好。platform-tools 还没装的时候这个路径存在但不生效不影响什么。export ANDROID_HOME$HOME/android-sdk export ANDROID_SDK_ROOT$ANDROID_HOME export PATH$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$PATH写完之后source ~/.bashrc让变量立即生效。然后验证最核心的东西sdkmanager --version如果输出一个版本号说明工具本身已经能跑环境变量也认到了。如果提示command not found先echo $ANDROID_HOME看变量是否空再看ls $ANDROID_HOME/cmdline-tools/latest/bin里有没有 sdkmanager。我见过很多次翻车是路径里多个斜杠或者拼错大小写因为 Linux 路径区分大小写Android 目录名全是小写。一个需要留意的点如果之前装过旧版 Android 工具链PATH 里可能已经有一个cmdline-tools/bin路径指向旧版本。新旧同时存在时which sdkmanager出来的那个才真正生效建议把老的路径从 PATH 里去掉避免两个版本互相干扰。3.4 第一个实例接受许可并安装 platform-tools工具能跑之后第一件事是接受所有 SDK 组件的许可协议然后安装最小可用集合。第一次跑 sdkmanager 的时候它会往$ANDROID_HOME/licenses目录写授权文件这个步骤不做后面安装任何组件都会卡在确认环节。用yes |管道可以直接把所有协议一并接受省去手动输入 y 的麻烦。yes | sdkmanager --licenses sdkmanager --install platform-tools platforms;android-34 build-tools;34.0.0第一条命令把当前 SDK 已知的所有 license 接受并落盘。第二条安装三样东西platform-tools是 adb、fastboot 等调试工具的集合platforms;android-34是 Android 14 的平台文件里面有 android.jar编译时要用build-tools;34.0.0是构建工具包括 aapt2、zipalign、apksigner。组件名里的分号是包名的一部分不能省略也不能替换成别的符号。安装完成后验证一下 adb 是否可用adb version如果输出 Android Debug Bridge version 相关信息说明整个链路已经通了。第一次跑 sdkmanager 时终端会输出下载进度网络不好时进度条可能停很久不要急着 CtrlC可以先看是不是卡在 license 确认上。这一步跑通之后后面装什么组件都只是换个包名的事。4. 不打开 Android Studio 的日常sdkmanager、avdmanager 与 apkanalyzer 实战4.1 sdkmanager 的完整用法列出、安装、精确匹配sdkmanager 是整套工具里使用频率最高的命令它的核心操作就三类列出、安装、卸载。刚装好工具时你可能想知道现在哪个 API Level 的 platform 是可用的或者自己装了什么。两条 list 命令的差别要分清--list列出服务器上所有可安装的组件--list_installed只列本机已装的。sdkmanager --list sdkmanager --list_installed sdkmanager --install platform-tools platforms;android-34 sdkmanager --uninstall build-tools;34.0.0--list的输出会很长建议用sdkmanager --list | grep platforms;android过滤只看 platforms。包名必须精确匹配比如platforms;android-34和platforms;android-33是两个不同包不存在模糊匹配。--uninstall同样要写完整包名卸载不会删依赖需要你手动评估哪些相关的包可以一起卸。还有几个实用参数值得记一下--channel3可以列出金丝雀版本适合想提前体验新 API 的开发者但别用在构建机上--verbose输出详细日志排查网络问题时有帮助--sdk_root$ANDROID_HOME显式指定根目录适用于没设置环境变量的场景。注意新版 sdkmanager 用--install参数安装旧版习惯是直接写包名sdkmanager platforms;android-34新版也兼容这种写法但推荐用带参数的格式。如果你发现装的 platform 版本和项目要求的对不上先用sdkmanager --list_installed确认现状再用--install补装对应版本。Gradle 构建时经常报错说缺少某个 build-tools 版本就是因为 sdkmanager 装的版本和build.gradle里buildToolsVersion指定的不一致命令行这边装一下就好了。4.2 avdmanager不启动 IDE 建模拟器avdmanager 负责虚拟设备AVD的创建和销毁。命令行建模拟器最大的价值在于 CI 场景无头跑 UI 测试时需要一台启动的模拟器而不可能让 Jenkins 去打开 Android Studio 点创建。用 avdmanager 建 AVD 之前需要先装 system-image 和 emulator 两个组件否则之后创建会失败。sdkmanager --install system-images;android-34;google_apis;x86_64 emulator avdmanager create avd -n ci_test -k system-images;android-34;google_apis;x86_64 -d pixel_5 avdmanager list avd第一行安装模拟器程序和系统镜像。system-image 的包名三个分号分段system-images;android-34是 API 版本google_apis表示带谷歌 APIx86_64是镜像架构如果你的机器是 ARM 就选arm64-v8a。第二行创建 AVD-n是设备名-k是镜像包名-d是设备配置文件。第一次创建时终端会问是否创建自定义硬件配置直接输入no回车用默认配置就行。启动模拟器的命令在 emulator 目录下面不建 AVD 也能执行但没有设备可启动。无头模式跑测试时一般这样启动$ANDROID_HOME/emulator/emulator -avd ci_test -no-window -no-audio -gpu swiftshader_indirect-no-window是不显示模拟器窗口-no-audio关掉音频-gpu swiftshader_indirect用软件渲染这三个参数组合是 CI 上跑模拟器的标准配置。启动后可以用adb wait-for-device等待设备就绪再跑测试。注意模拟器启动需要几秒到几十秒CI 脚本里要留足等待时间。4.3 apkanalyzer 与 lintAPK 的体检和静态检查拿到一个 APK 之后想快速了解它是什么包名、targetSdk 多少、用了哪些权限不需要反编译工具apkanalyzer 就够了。它在命令行工具包里自带直接对 APK 文件执行。这个命令在排查问题时特别有用比如客户反馈的包版本不对用一条命令就能确认这个 APK 到底是不是最新的。apkanalyzer manifest print app-debug.apk apkanalyzer apk summary app-debug.apk apkanalyzer dex packages app-debug.apk第一条打印 APK 的 AndroidManifest.xml 内容能看到包名、版本号、权限声明、四大组件等第二条输出 APK 的基本信息摘要包含最低 Android 版本、目标 SDK 版本第三条列出 dex 文件里的包结构和类数量可以用来快速判断一个 APK 是否打过混淆、是否包含某个类。这些命令不需要启动任何服务执行速度和文件大小有关一般一秒内出结果。lint 静态检查在命令行工具里也有对应入口但对单个 APK 文件检查比较少见更多是对工程源码跑。常见做法是直接执行./gradlew lint生成的报告在app/build/reports/lint-results-debug.html。命令行工具包里的 lint 脚本主要用于脱离 Gradle 的场景比如在 CI 里对一份 pull 下来的代码单独检查。静态检查的坑在于默认规则集有时候过严很多团队会在lint.xml里把不必要的规则关掉不然构建分会挂在一些无伤大雅的告警上。4.4 把这套工具接进 CI无 UI 场景的最小配方命令行工具在 CI 里的定位是“基础镜像的一部分”而不是每次构建时现下载。GitHub Actions 和 Jenkins 常见做法是把下载、解压、装 SDK 组件的过程固化成脚本缓存 SDK 目录让每次构建复用。第一次构建先把环境铺好后续构建直接走缓存省掉最耗时的下载环节。set -e curl -fsSL -o /tmp/cmdtools.zip https://dl.google.com/android/repository/commandlinetools-linux-13114758_latest.zip unzip -q /tmp/cmdtools.zip -d $ANDROID_HOME yes | sdkmanager --licenses sdkmanager --install platform-tools platforms;android-34 build-tools;34.0.0 sdkmanager --list_installed | tee /opt/android-sdk/packages.txt这里的set -e让脚本在任一步失败时立即退出避免在残缺环境下继续构建。注意下载链接里的版本号用下划线连接和文件名commandlinetools-linux-13114758-latest.zip里的连字符不同拼错会 404。CI 脚本里我一般会把版本号单独定义成一个变量比如CMDTOOLS_VERSION13114758方便以后升级时只改一行。最重要的一个经验不要把 CI 脚本写成每次都拉最新包。文件名里的latest会害人今天最新的版本过两个月就变了锁版本号才能保证构建可复现。团队内部如果网络到 Google 仓库不稳定常见做法是把 zip 和常用 SDK 组件打包放到内网对象存储或者 Nexus 上CI 从内网拉取。这种方案同时解决了下载速度和版本固定两个问题。5. 命令行工具常见坑与排错从 java 报错到 SDK 装完用不了的 5 个现场5.1 sdkmanager 一执行就报 Java 异常现象执行sdkmanager --version时直接抛Error: Could not find or load main class com.android.sdklib.tool.sdkmanager.SdkManagerCli看起来像是工具包不完整。原因绝大多数情况是 JDK 版本不对。新版 commandlinetools 的 jar 包编译目标版本较高用 JDK 8 跑会因版本过低无法加载类。其次是目录结构错误sdkmanager 脚本通过自身路径定位 lib 下的 jar 包如果cmdline-tools/latest层级不对脚本就找不到主类。解决先java -version确认版本低于 17 就先升级。再确认目录结构ls $ANDROID_HOME/cmdline-tools/latest/lib能看到一堆 .jar 文件source.properties在上一级。如果目录层级多了或少了重新按 3.2 节的方式整理。有个命令行能直接定位问题which sdkmanager看它是否指向了你以为的路径以此排除 PATH 里多个版本冲突。5.2 下载组件卡在 Fetching 或提示 Cannot download现象sdkmanager --install执行后终端长时间停在Fetching阶段进度条不动或报Cannot download后中断。重试多次仍失败偶尔成功但下次又不行。原因sdkmanager 默认从 Google 仓库下载组件网络链路慢或超时会被视为失败。另一个隐藏原因是 license 未接受时部分版本会一直挂在确认状态不报错看起来像卡死。重试时重复的临时文件有可能残留影响下一步操作。解决先把 license 处理掉yes | sdkmanager --licenses。然后用--verbose重跑一次安装看日志停留在哪个 URL判断是哪个组件拉取失败。对依赖公网下载的环境常见做法是配置国内镜像源通过修改$ANDROID_HOME/cmdline-tools/latest/lib/sdkmanager.cfg指定仓库地址sdkman.repohttps://mirrors.example.com/android/repository这里mirrors.example.com是假设的内网镜像域名实际部署时换成自己团队维护的镜像地址。改完后用sdkmanager --list验证镜像是否可用能看到组件列表就说明仓库生效。每次安装前也可以--verbose看实际请求路径确认走的是镜像而不是默认仓库。删掉$ANDROID_HOME下带 .tmp 后缀的残留临时文件再重试能解决一部分“装了半截”的怪问题。5.3 装完 build-tools 却找不到 aapt2现象Gradle 构建时报Failed to find Build Tools revision 34.0.0或 Android Studio 提示 SDK Build Tools 缺失。但运行sdkmanager --list_installed明明显示build-tools;34.0.0已经安装了。原因第一种可能是 Gradle 请求的 build-tools 版本和你安装的版本不完全一致比如项目要34.0.0而你装的是34.0.0-rc1这在只装了 preview 版本时经常发生。第二种是ANDROID_HOME环境变量指向的 SDK 路径和项目实际使用的 SDK 路径不同Gradle 没认到sdkmanager装的那个 SDK。第三种是构建工具安装时目录写入权限有问题文件没写全。解决先确认本机到底装了哪个版本直接看目录ls $ANDROID_HOME/build-tools/ ls $ANDROID_HOME/build-tools/34.0.0/aapt2如果目录里没有对应版本用sdkmanager --install build-tools;34.0.0补装。如果版本存在但 Gradle 报缺失检查项目根目录local.properties里的sdk.dir是否指向ANDROID_HOME用绝对路径写死是最可靠的方案。另外可以用aapt2 version验证二进制能否执行如果提示权限不足chmod x加可执行权限。5.4 Android Studio 与命令行工具互不认SDK 路径不一致现象命令行里 adb、sdkmanager 都能跑但 Android Studio 打开项目报SDK location not found。两个环境各认各的路径互不相通。原因Android Studio 通过local.properties或自身的 SDK Location 设置来确定 SDK 路径不会自动读取 shell 的环境变量。命令行工具通过ANDROID_HOME定位两边独立管理。如果你先在命令行装了 SDK 在~/android-sdk而 Android Studio 默认找~/Library/Android/sdkmacOS或其他路径自然找不到。解决以命令行安装的目录为准在项目根目录创建或修改local.propertiessdk.dir/home/yourname/android-sdk把路径换成自己的绝对路径。如果是新建工程也可以直接在 Android Studio 的 Project Structure 里把 SDK 路径指定到同一目录。一个反面典型是两边各自装了独立 SDK占了两份磁盘空间还经常因为版本不同出现怪问题。经验是开发机上只维护一份 SDK命令行和 IDE 都用它。5.5 手滑删错目录或权限被 root 占用现象sdkmanager 安装组件时写到一半报 Permission denied或者整个 SDK 目录被人误删所有环境变量都失效。原因最常见的两种一是有同事为了方便用sudo sdkmanager安装组件导致 SDK 下所有目录的 owner 变成 root普通用户之后想装任何东西都没有写权限越补越乱二是有人rm -rf $ANDROID_HOME时少打了一个字母把整个 SDK 连同 cmdline-tools 一起删了。解决权限错乱的情况一个命令就能治好sudo chown -R $USER:$USER $ANDROID_HOME把所有文件归回当前用户之后不要再碰 sudo。误删目录没有后悔药只能按第 3 章的流程重新下载 zip、解压、重装 SDK 组件。但有个能减少损失的习惯把sdkmanager --list_installed的输出保存下来重装的时候照着列表一条条装回去。这个文件我一般放在 SDK 根目录外面避免随 SDK 一起被误删。删除操作前先echo $ANDROID_HOME确认路径是否为空这能拦下大部分手滑。6. 验证安装与进阶配置一条命令确认 SDK 状态与三个高频技巧6.1 快速健康检查一条命令连串验证平时我检查一台机器的 Android 环境是否健康会直接把三个命令连起来跑先看工具版本再看已装组件清单最后看 adb。三步都通过这个环境基本就能直接开干。sdkmanager --version sdkmanager --list_installed adb version保证前一条成功才执行下一条任一步失败就能定位问题在哪个环节。sdkmanager 版本号报错多半是 JDK 或目录问题list 结果缺失组件说明安装不完整adb 报 command not found 则检查 PATH 里是否包含 platform-tools。这套检查同样适合写成一个check_android_env.sh脚本新入职同事拉下来跑一遍就能确认环境就绪。6.2 三个用过就回不去的小配置第一个是别名。命令行操作里sdkmanager --list输出太长我会在.bashrc里加alias sdklistsdkmanager --list加alias sdksdkmanager --install少打一串是一串。第二个是对 AVD 设备名的约定团队里建模拟器统一用“项目名_用途_架构”格式比如ci_test_x86_64避免 AVD 一多根本分不清谁是谁。第三个是环境变量在 CI 里的留档习惯把每个版本号写进一个 environment 文件让整个构建链路用的同一个 SDK。我自己踩得最狠的一次是第 5 章的 5.1新工具配了旧 JDK报错报得莫名其妙查了半天才发现是版本不匹配。现在拿到任何新版本的 commandlinetools我会先java -version再决定要不要继续装。这套工具的坑不算少但摸清楚规律之后它确实是 Linux 上搓 Android 构建环境最直接的路。希望帮到你。本文还有配套的精品资源点击获取
返回列表