资讯详情

资讯详情

Android命令行工具拆包实战:用commandlinetools搞定SDK管理、模拟器与lint

简介这是面向 Windows 平台开发者的 Android 命令行工具最新版压缩包适合希望绕开庞大 IDE、通过终端完成日常开发工作的场景。压缩包共有 108 个文件以 95 个 jar 工具库和 10 个 bat 启动脚本为主附带属性配置与说明文档整体体积约 136.41MB目前已有 544 人学习下载。无需安装 Android Studio即可借助内置的 sdkmanager 按需下载系统镜像、开发库、接口文档与模拟器组件也能完成 APK 分析、虚拟设备管理、代码检查、打包混淆与资源压缩等操作工具集支持创建和管理多个安卓项目可将应用快速部署到连接的设备或模拟器上也适用于自动化构建、测试和报告生成等重复性任务。目录结构紧凑便于直接加入脚本或持续集成流程适合具备命令行基础、追求轻量化开发或需要搭建标准化构建流程的开发者取用。1. 不用 Android Studio 也能干 Android 开发的活commandlinetools 拆包笔记作为一个常年靠键盘干活的人拿到commandlinetools-win-13114758-latest.zip的第一反应是终于可以甩开 Android Studio 那个笨重的 IDE 了。这个压缩包解压后就是 Android 官方的命令行工具集里面躺着sdkmanager、avdmanager、d8、r8、lint这些实打实的家伙。平时我们装 Android Studio 时这些工具会被自动带上但如果你只需要下载 SDK 组件、管理模拟器、跑代码检查完全没必要装一个几个 GB 的 IDE一个几十 MB 的命令行工具包就够了。适合谁用CI 流水线维护者、喜欢 Vim/Emacs 的老派开发者、还有那些开发机配置不高的同学。接下来我把自己拆这个包的整个过程、遇到过的坑、验证过的命令一次性写清楚。2. 拆开压缩包10 个 bat 工具分别干什么、怎么用老规矩先把 zip 解压到一个干净目录比如D:\android-cmdline-tools。解压后你会发现目录结构是cmdline-tools但在某些发行版里工具不会自动识别需要手动调整目录层级。这一步不做好后面的任何命令都会报错所以先从结构说起。2.1 工具清单全解析每个 bat 的定位与选择解压后进入cmdline-tools\bin里面有一堆.bat。我这个包里有 10 个可执行入口它们都是 Windows 下的启动器真正的逻辑在对应的.jar里。下面这张表是核心地图建议保存一份省得每次翻文档文件名用途常用场景apkanalyzer.bat分析 APK 文件查看 manifest、dex、资源等信息检查三方 APK 的包名、权限、SDK 版本sdkmanager.batSDK 包管理器下载、更新、卸载 SDK 组件安装platforms;android-33、emulator等resourceshrinker.bat资源压缩工具配合bundletool减少 APK 资源体积发布前对资源做瘦身avdmanager.bat创建和管理 Android 虚拟设备AVD在命令行创建模拟器配置screenshot2.bat对已连接的设备或模拟器截图自动化测试时快速抓图lint.bat静态代码检查发现潜在 bug 和性能问题提交前跑一遍质量门禁profgen.bat生成 profile 文件用于启动性能优化配合 Baseline Profile 生成retrace.bat反混淆堆栈 trace把混淆后的类名映射回原始名字线上崩溃日志还原r8.bat代码混淆与压缩工具替代 ProGuard发布 release 包时做裁剪d8.batJava bytecode 转 dex 工具替代旧的 dx把.class转成 Android 可执行的.dex这些工具里最常用的是sdkmanager、avdmanager、lint和d8。r8打包时才会碰retrace是出生产事故后的救命稻草apkanalyzer在分析三方包时非常顺手。而resourceshrinker和profgen属于进阶组件普通小项目可能一次都用不上。我个人的选型建议是如果你只做 SDK 开发和命令行构建记住sdkmanager就够你装完所有东西如果你想在脚本里做质量检查lint比 IDE 里的 Inpect Code 更容易集成如果你在维护旧项目d8和r8会是你最常面对的。至于screenshot2说句实话我用adb exec-out screencap的时候比它多但它在某些自动化框架里确实是标准配置。2.2 sdkmanager包管理器核心用法与三个常用参数sdkmanager是这个工具包里的“总闸门”。没有它你这台机器就装不了任何 Android SDK 组件。它支持的动作很简单列出版本、安装、卸载、更新。难在命令参数和包名的格式。先看能装什么# 在 cmdline-tools 解压目录下执行 sdkmanager.bat --list这个命令会输出一个很长的列表分成Available Packages和Installed Packages两部分。输出会带很多换行Windows 下建议过滤一下sdkmanager.bat --list | findstr platforms;android-3这里findstr是 Windows 自带的文本过滤命令相当于 Linux 的grep。如果你在 PowerShell 里用Select-String代替同样效果。注意包名里的分号在命令行里是分隔符所以包名必须用双引号包起来这是新手第一个报错来源。安装一个平台包sdkmanager.bat platforms;android-33这条命令会下载 Android 13API 33的平台文件包括android.jar、构建依赖等。安装完成后--list里它会出现在Installed部分。除了平台包常用的还有这些sdkmanager.bat build-tools;33.0.1 sdkmanager.bat platform-tools sdkmanager.bat emulator sdkmanager.bat system-images;android-33;google_apis;x86_64第一行是编译工具链里的aapt2、zipalign那些可执行文件第二行是adb和fastboot第三行是模拟器本体第四行是模拟器要用到的系统镜像。如果你只想写纯 Java 的 SDK 库第一、二行必装要跑模拟器第三、四行必装。升级组件也是一句话sdkmanager.bat --update它会扫描当前已装组件再把有新版的都更新掉。但这里我要多说一句在 CI 环境里我从来不跑--update而是严格锁版本因为工具链一升级构建结果可能就变了。这个在第 4 章会展开。2.3 目录结构陷阱cmdline-tools/latest 的由来解压后直接执行 bat很可能碰到这么一句The tools must be located in the cmdline-tools/latest directory。这是官方为了支持多版本切换做的改动工具必须在cmdline-tools下的某个版本目录里而latest是默认约定。我的处理方式是手动重建目录mkdir D:\android-cmdline-tools\cmdline-tools\latest然后把 zip 里cmdline-tools目录下的所有内容bin、lib、NOTICE.txt等复制到latest里。最终结构是D:\android-cmdline-tools\ cmdline-tools\ latest\ bin\ lib\这样sdkmanager.bat才会正常工作。为什么有这个设计因为它允许你同时装多个版本的 cmdline-tools然后用sdkmanager cmdline-tools;version引入和管理。但这带来的麻烦是新手不知道这个结构以为解压就能用结果第一步就卡住。后面第 4 章我会再讲一个和ANDROID_HOME相关的坑。3. 环境配置与基本演练从解压到跑通 lint工具只有跑起来才有价值。这一章按「配置 → 验证 → 干活」的顺序来每一步我都会把参数含义讲透不然换了个版本你就不知道怎么改了。3.1 准备 JDK 并设置环境变量Android 命令行工具大部分基于 Java所以必须先有 JDK。官方要求 JDK 11 或更高版本取决于你选的 build-tools 版本。先检查java -version如果没输出请先安装一个 JDK。装好后设置环境变量。在 PowerShell 里临时设置当前会话$env:JAVA_HOME C:\Program Files\Java\jdk-17 $env:ANDROID_HOME D:\android-sdk $env:Path ;%JAVA_HOME%\bin;D:\android-cmdline-tools\cmdline-tools\latest\bin;%ANDROID_HOME%\platform-tools;%ANDROID_HOME%\emulator这里四段路径各有各的意义JAVA_HOME\bin让java和javac可用cmdline-tools\latest\bin让sdkmanager和avdmanager可用platform-tools让adb可用装完 platform-tools 后才有emulator让模拟器启动器可用装完 emulator 后才有如果你想让配置永久生效用系统设置里的「编辑环境变量」把上面路径追加到Path注意别覆盖原有值。我习惯在用户变量里设置ANDROID_HOME不设成全局系统变量这样多个项目切换 SDK 版本时更灵活。验证是否配置成功sdkmanager.bat --version如果能输出版本号说明入口找对了。如果你没有设置ANDROID_HOME那么sdkmanager会默认使用用户目录下的AppData\Local\Android\Sdk。为了避免路径歧义我更喜欢显式指定 SDK 根目录sdkmanager.bat --sdk_rootD:\android-sdk --version--sdk_root这个参数要放在子命令前面它告诉工具SDK 安装在哪个目录。如果你已经设置了环境变量这步可以省略但 CI 脚本里我建议每次都带防止环境变量被污染。3.2 安装最小组件并验证环境完整性一个新机器上我会装这么几个组件sdkmanager.bat --sdk_rootD:\android-sdk platform-tools sdkmanager.bat --sdk_rootD:\android-sdk build-tools;33.0.1 sdkmanager.bat --sdk_rootD:\android-sdk platforms;android-33 sdkmanager.bat --sdk_rootD:\android-sdk cmdline-tools;latest前三个是好理解的。第四个cmdline-tools;latest会把命令行工具自己也纳入 SDK 管理装到D:\android-sdk\cmdline-tools\latest。注意这和你手动解压的那个目录是两回事。安装后你的 SDK 根目录里会多出cmdline-tools子目录以后可以直接用这个目录下的工具而不必依赖手动解压的路径。验证安装D:\android-sdk\platform-tools\adb.exe version如果你能看到 adb 版本说明平台工具没问题。再看 build-toolsD:\android-sdk\build-tools\33.0.1\aapt2.exe versionaapt2是资源编译器后续打包、分析 APK 都靠它。这个命令输出版本号的话你的编译工具链就绪。3.3 跑通第一个 lint 检查从最小项目开始lint 需要一个 Android 项目结构才能工作。我带你创建一个最简陋但完整的项目骨架不用 Gradle纯手写。创建目录mkdir D:\demo-lint\app\src\main mkdir D:\demo-lint\app\src\main\res\values写AndroidManifest.xml?xml version1.0 encodingutf-8? manifest xmlns:androidhttp://schemas.android.com/apk/res/android packagecom.example.demolint application android:labeldemo / /manifest写res\values\strings.xmlresources string nameapp_namedemo/string /resources这两个文件是 lint 的最低要求一个 manifest 给出包名和应用信息一个资源文件提供引用。现在运行 lintD:\android-cmdline-tools\cmdline-tools\latest\bin\lint.bat D:\demo-lint如果配置正确终端会输出检查结果比如MissingApplicationIcon这类警告。lint 默认只输出报告不阻塞构建。如果你想让它作为质量门禁加参数lint.bat D:\demo-lint --exitcode --warnings-as-errors--exitcode让 lint 在有错误时返回非零值--warnings-as-errors把警告也升级成错误。CI 里这样用就不会放过任何小问题。不过要注意第一次运行时 lint 会扫描全项目生成一个lint-report.html在项目目录下这也是一个你可以接进报告平台的产物。4. 常见问题与避坑指南七个真实踩坑记录命令行工具没有图形界面出错时它只会回你一行文字。这一章我把自己和同事踩过的坑整理出来按「现象 → 原因 → 解决」的顺序写希望能帮你省下几小时的研究时间。4.1 现象与原因速查表现象最常见原因解决方向执行 bat 后闪退没有任何输出没装 JDK或JAVA_HOME指向错误先跑java -version排查提示找不到sdkmanagerPATH 没配到cmdline-tools\latest\bin用绝对路径执行或修正 PATH提示 Command line tools component is missing解压目录结构缺少latest层级按第 2.3 节重建目录d8.bat报 Cannot fit requested classes in a single dex file方法数超过 64K需要 multidex改用d8 --multi-dexemulator启动黑屏系统镜像与主机架构不匹配确认是x86_64还是arm64-v8asdkmanager --list输出乱码编码问题Windows 控制台默认 GBK先执行chcp 65001切 UTF-8安装组件时一直卡在 Fetching网络问题或代理冲突检查 JDK 代理设置必要时关代理4.2 踩坑一安装完 platform-tools 还是找不到 adb现象sdkmanager.bat platform-tools显示安装成功但终端里输入adb依然提示 不是内部或外部命令。原因platform-tools被安装到了%ANDROID_HOME%\platform-tools但你可能没设过ANDROID_HOME于是它装到了默认目录C:\Users\[用户名]\AppData\Local\Android\Sdk\platform-tools。你的 PATH 里没有这个目录自然找不到。解决先查实际安装路径。有两种方式一是看sdkmanager --list_installed输出的 SDK 根目录二是直接搜索adb.exe在你的用户目录下。知道路径后设置环境变量set ANDROID_HOMED:\android-sdk set PATH%ANDROID_HOME%\platform-tools;%PATH%然后重新打开终端。记住环境变量改完必须重开终端不是我自己啰嗦这真的是每个人都会翻车的地方。从那以后我每次装完 SDK 组件都会顺手执行where adb验证一下。4.3 踩坑二d8 转换后没有 dex 文件现象照着文档执行d8.bat Main.class结果没有生成classes.dex反而报Class X doesnt implement interface Y之类的错。原因d8处理的是 Java 字节码但它要求类结构完整并且引用的所有依赖都在 classpath 里。如果你只给了一个Main.class而它依赖了 Android 框架类d8根本找不到自然失败。很多教程默认你是在 Android 工程里调用所以省略了依赖参数但新手很容易照抄到自己的独立类上。解决把android.jar加到--lib参数d8.bat --lib D:\android-sdk\platforms\android-33\android.jar Main.class如果有第三方 jar 依赖再加--classpathd8.bat --lib D:\android-sdk\platforms\android-33\android.jar --classpath libs\some.jar Main.class注意是--classpath不是-cpd8 不支持简写。我一般在脚本里先把所有 jar 收集到一个列表文件再用 for 循环拼参数避免手写漏项。4.4 踩坑三avdmanager 创建模拟器失败现象执行avdmanager.bat create avd -n test -k system-images;android-33;google_apis;x86_64提示Cannot create AVD from this SDK。原因avdmanager需要完整的 SDK 平台和系统镜像。你很可能只装了platforms没装system-images或者镜像包名和你写的不一致比如少写了google_apis这个中间段。解决先确认系统镜像真的装了sdkmanager.bat --list_installed | findstr system-images如果没装执行sdkmanager.bat system-images;android-33;google_apis;x86_64然后创建时加echo no来跳过交互式问题echo no | avdmanager.bat create avd -n test -k system-images;android-33;google_apis;x86_64echo no的意思是当程序询问「是否用自定义硬件文件」时回答 no直接用默认配置。这是无人值守创建的典型手法。4.5 踩坑四升级工具包导致构建结果发生变化现象同一份代码上周构建正常这周 CI 上 APK 的资源合并报错或者 dex 方法数超限。原因CI 里可能执行了sdkmanager --update把 build-tools 从 33.0.1 升到了 33.0.2 之类的小版本。工具链的细微变化足以影响资源编解码行为尤其是资源和 dex 优化相关工具。解决把工具链版本锁死在项目配置文件里脚本里使用绝对路径调用指定版本的aapt2、d8、r8不依赖 PATH 自动匹配。同时禁止 CI 执行--update只有手动确认后才升级。我见过团队因为dx换成d8导致发布流程崩掉从那以后所有构建脚本里都强制锁定build-tools版本。5. 实战用命令行完成模拟器创建、dex 转换与 lint 门禁这一章我们把前面所有知识串起来完成三个任务创建一个可用的 AVD用 javacd8 转出一个 dex 文件用 lint 给一个简陋项目做质量检查。走完这一套你对 Android 构建链路的理解会比装 IDE 点鼠标要深得多。5.1 创建并启动一个无界面模拟器假设你已经装好了emulator和system-images我们来创建一个 AVD。先看现有设备配置avdmanager.bat list device输出里有很多设备 ID比如pixel_5、pixel_6后面-d参数就填这个 ID。创建 AVDecho no | avdmanager.bat create avd -n demo_avd -k system-images;android-33;google_apis;x86_64 -d pixel_5参数含义-n demo_avd给你的虚拟设备起名-k系统镜像包名必须和sdkmanager --list里的完全一致-d pixel_5参考的设备定义决定屏幕大小、分辨率创建成功后启动模拟器不加窗口D:\android-sdk\emulator\emulator.exe -avd demo_avd -no-window -no-audio -gpu swiftshader_indirect-no-window表示后台运行-no-audio关掉音频-gpu swiftshader_indirect使用软件渲染。这对没有独立显卡的 CI 机器很友好。启动后等待几十秒然后验证adb devices如果输出里出现emulator-5554说明系统起来了。注意如果报HAXM is not installed或WHPX is not enabled要去 BIOS 打开虚拟化技术或者改用 ARM 镜像。这个我在第 4 章说过了这里不再重复。5.2 手工编译 javac d8 生成 dex现在写一个纯 Java 类体验字节码转 dex 的过程。创建目录mkdir D:\demo-dex\src写Hello.javapublic class Hello { public static void main(String[] args) { System.out.println(Hello from command line); } }编译cd D:\demo-dex javac -source 8 -target 8 -d classes src\Hello.java-source 8 -target 8强制生成 Java 8 字节码d8对高版本字节码兼容性不够好压到 8 最稳。然后转 dexd8.bat --output dex-output --lib D:\android-sdk\platforms\android-33\android.jar classes\Hello.class这里--output dex-output指定输出目录--lib指定 Android 平台 jar。运行完dex-output目录下会多出classes.dex。怎么验证内容用apkanalyzerapkanalyzer.bat dex list dex-output\classes.dex如果能看到LHello;这样的类描述符说明 dex 生成成功。这个 dex 还不能直接安装因为它不是完整 APK但你可以把它作为构建产物的一部分配合aapt2和 signing 工具继续打包。5.3 把 lint 变成构建门禁继续用第 3.3 节的项目我们把 lint 接到一个批处理流程里。写一个run_lint.batecho off setlocal set LINT%ANDROID_HOME%\cmdline-tools\latest\bin\lint.bat set PROJD:\demo-lint call %LINT% %PROJ% --exitcode --warnings-as-errors if errorlevel 1 ( echo Lint failed. Check lint-report.html exit /b 1 ) echo Lint passed. endlocal注意if errorlevel 1是批处理里判断退出码的方式。这样 CI 在 lint 不通过时可以直接终止流水线。你也可以把--baseline baseline.xml参数加进去允许历史遗留问题存在只拦截新增问题。这个技巧对老项目特别有用。6. 进阶把整套流程封装成一键脚本并养成版本锁死习惯命令行工具最大的价值不是手动一条条敲而是变成脚本的一部分。这一章我会给出一份可复用的批处理骨架并说说我个人的纪律。6.1 一键完成 SDK 安装、编译、dex、lint 的骨架用 Windows 批处理写一个build_all.batecho off setlocal set ANDROID_HOMED:\android-sdk set CMD_LINED:\android-cmdline-tools\cmdline-tools\latest\bin set PROJ_DIRD:\demo-lint set BUILD_TOOLS33.0.1 echo [step 1] ensure sdk components... call %CMD_LINE%\sdkmanager.bat --sdk_root%ANDROID_HOME% platform-tools call %CMD_LINE%\sdkmanager.bat --sdk_root%ANDROID_HOME% build-tools;%BUILD_TOOLS% call %CMD_LINE%\sdkmanager.bat --sdk_root%ANDROID_HOME% platforms;android-33 echo [step 2] compile java... cd D:\demo-dex javac -source 8 -target 8 -d classes src\Hello.java echo [step 3] dex... call %ANDROID_HOME%\build-tools\%BUILD_TOOLS%\d8.bat --output dex-output --lib %ANDROID_HOME%\platforms\android-33\android.jar classes\Hello.class echo [step 4] lint... call %CMD_LINE%\lint.bat %PROJ_DIR% --exitcode --warnings-as-errors echo all done. endlocal这里几个关键点call用来调用另一个 bat如果少了call批处理会在执行完子脚本后直接退出后面的命令就不会跑--sdk_root每次显式指定避免环境变量污染BUILD_TOOLS变量锁死版本升级工具只需要改一处6.2 我的一些小习惯写到这里我想说一个自己吃了不少亏才养成的习惯每次拿到新的命令行工具包第一件事不是去跑安装而是先重建目录结构、确认版本然后跑一条最基础的sdkmanager --sdk_root... --list | findstr platforms;android-把输出留档。这样如果后面环境出问题至少知道最开始是什么状态。另外我所有脚本里都会先设置setlocal防止环境变量泄露到父进程。还有一点sdkmanager的安装记录都写在%ANDROID_HOME%\.knownPackages文件里查不到安装历史时翻这个文件就能看到你装过什么比重新--list要快。最后升级工具链时一定要手动跑一次完整构建对比产物别自动更新。希望这篇拆包笔记能帮你在纯命令行环境下把 Android 开发跑起来。如果遇到具体报错先按第 4 章的排查顺序走一遍多半能自己解决。本文还有配套的精品资源点击获取
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →