r22 platform-tools:adb/fastboot老设备连接避坑

发布时间:2026/10/27 12:15:56
r22 platform-tools:adb/fastboot老设备连接避坑 简介platform-tools_r22-windows.zip 是面向 Android 应用开发与设备调试人员的 Windows 平台工具集合定位为连接电脑与真机、完成固件刷写及性能分析的命令行工具箱。包内共 21 个文件以 6 个 exe 可执行程序、2 个 dll 动态链接库和 2 个 py 脚本为主辅以 html 报告模板、xml 配置、css/js 静态资源及 license、notice 等说明文档压缩包约 1.76MB体积轻便。已有 316 人学习适合需要脱离完整 IDE、在命令行完成设备管理的开发者参考。其价值集中在 ADB、Fastboot、systrace、hprof-conv、sqlite3 等工具链既能进行设备调试、文件传输、应用安装卸载与分区映像刷写也能采集系统级 CPU、GPU 与内存数据并生成可视化报告配合内存转换工具排查泄漏、借助 GPU 渲染追踪优化帧率与 UI 流畅度。对于想理解 Android 平台工具组成、补齐调试与性能分析手段的中级开发者这份工具包提供了较完整的命令行能力入口。1. 一台工装电脑的 adb 只认这个目录产线上有一台老工装电脑系统盘里躺着一个很早以前解压出来的文件夹里面就四个可执行文件和两个 DLL。同一条 USB 线、同一台设备我在新机器上装了新版 platform-toolsadb devices出来是空的设备管理器里倒是能看到设备把那个老文件夹整个拷过来adb devices立刻吐出一行序列号。这种事在维护老固件、老夹具、老烧录工位的场景里并不罕见——platform-tools 不是一个越新越好的包。platform-tools_r22-windows.zip就是 Android SDK 里的 platform-tools 组件包revision 22Windows 版解压即用不需要安装器。包里最核心的是adb.exe和fastboot.exe外加 Windows 下访问 USB 必需的两个动态库还有一份记录版本号的source.properties。它解决的是在新版工具链上跑不通的老设备连接与刷写这一类具体问题握手失败、服务端版本打架、老系统跑不动新构建、厂商脚本硬编码了路径。适合三类人维护存量设备与老固件的一线工程师、需要复现历史问题的人、以及在 32 位或运行库受限的机器上做交付的人。2. 拆包先看清文件r22 目录里那几样东西各管一段拿到 zip 双击adb.exe窗口一闪就没了很多人第一反应是包坏了。其实这个行为本身是正常的——不带参数执行时它只打印帮助然后退出。判断包好不好得先把目录拆开知道每个文件负责哪一段链路出问题时症状才对得上号。2.1 文件职责边界与缺了会怎样先看一份典型的 r22 目录清单。不同渠道重打包的版本可能在附带目录上有出入但核心这几样是一致的以解压后的实际内容为准。文件职责缺失后的典型症状adb.exe客户端与服务端二合一命令直接不可用AdbWinApi.dllUSB 设备枚举与扫描的封装层进程起不来报找不到模块或 0xc000007bAdbWinUsbApi.dll底层 USB 端点读写能列出设备但 push/pull 卡死或报错fastboot.exebootloader 模式下的通信工具刷写类命令全部不可用source.properties版本元数据含Pkg.Revision脚本读版本失败SDK 侧识别不到NOTICE.txt许可声明无功能影响删了也能跑两个 DLL 的分工值得单独说一句因为它们的故障表现完全不同排障时这个区别很值钱。AdbWinApi.dll是进程加载阶段就要的缺了adb.exe连启动都启动不了报错信息通常很难看AdbWinUsbApi.dll是运行到实际收发数据时才用缺了以后adb devices可能照样能列出序列号但一执行adb push就挂住或者抛异常。所以看到设备能列出来但传不了文件第一反应不应该是线的问题先确认这个目录里 DLL 齐不齐。source.properties是个容易被顺手删掉的文件内容就一两行键值对Pkg.Revision那行写着 22。做版本巡检脚本的时候读这个文件比解析adb version的输出更稳因为输出格式在不同构建之间会变。早期的一些 platform-tools 包里还会带一个usb_driver目录里面有android_winusb.inf这类驱动安装信息文件可以让 Windows 手动指向它装驱动后来的版本把这部分挪走了。手上这个包有没有解压后看一眼就知道有的话先留着后面章节会用到。2.2 老版本在特定场景下反而更能用的三条原因第一条是服务端版本冲突。adb 是客户端/服务端架构你敲的每条命令都是客户端真正干活的是一个常驻后台、监听本机 5037 端口的服务端进程。服务端用的是哪个adb.exe启动的它就是哪个版本。机器上同时存在新旧两套 platform-tools 时先启动的那个占住端口后启动的客户端连上去双方版本号对不上就直接报adb server version (xx) doesnt match this client (yy)然后拒绝服务。老包里那套组合是自己跟自己配对的反而不会打架。第二条是构建本身对系统的要求。新版构建通常按较新的 Windows 和运行库编译部分老机器——尤其是还在跑 32 位系统、缺 VC 运行库、或者被组策略锁住不允许装东西的工装电脑——直接跑不起来报的不是 adb 的错误而是系统层面的加载失败。这种机器上老包是唯一能用的方案。第三条是上层工具链的硬编码。不少厂商的烧录脚本、测试工装、自动化产线程序里面写死了C:\android\platform-tools\adb.exe这个路径有的甚至会对adb version的输出做字符串判断版本不对就拒绝往下走。这类程序改动成本极高换包比改代码便宜得多。提示老版本能跑不等于该一直用。它是存量维护的手段不是新项目的默认选择。新设备、新协议、新特性还是得用新构建。2.3 解压、校验与 PATH三步落地第一步别急着解压到桌面。路径里带空格、带中文、层级太深都可能在某些老工具链里翻车我一般固定用C:\pt22这种短路径。解压前先算一次哈希留个底以后换机器复现时能确认拿到的是同一个包。# 1) 校验压缩包完整性把哈希值记下来存档 Get-FileHash .\platform-tools_r22-windows.zip -Algorithm SHA256 | Format-List # 2) 解压到无空格无中文的短路径 $dst C:\pt22 Expand-Archive -Path .\platform-tools_r22-windows.zip -DestinationPath $dst -Force # 3) 确认关键文件齐全重点看两个 DLL 在不在 Get-ChildItem $dst\platform-tools | Select-Object Name, Length | Sort-Object NameExpand-Archive在极老的 PowerShell 上不可用那就换 7-Zip 命令行或者右键解压效果一样。第三步的清单必须包含adb.exe、fastboot.exe、AdbWinApi.dll、AdbWinUsbApi.dll四项缺任何一项都别往下走直接重新下载。第二步是让命令在任意目录可用。我习惯先在当前会话里临时加 PATH 验证确认没问题再写进系统变量避免把系统 PATH 写坏。# 会话级临时生效只影响当前窗口验证用 $env:Path C:\pt22\platform-tools; $env:Path adb version # 确认无误后再写进用户级 PATH不需要管理员权限 $old [Environment]::GetEnvironmentVariable(Path, User) [Environment]::SetEnvironmentVariable(Path, $old ;C:\pt22\platform-tools, User)参数上要注意两点拼接时前面那个分号不能少User和Machine别搞混——写Machine需要管理员权限而且会影响这台机器上所有账户工装机多人共用时容易出事。写入后必须新开一个终端窗口才生效老窗口里的环境变量是启动时快照的不会自动刷新。有些工具链还会读ANDROID_HOME或ANDROID_SDK_ROOT来定位工具。单独一个 platform-tools 目录并不是完整的 SDK硬指过去可能让别的工具误判。我的做法是只在确实需要的机器上设设成C:\pt22platform-tools 的上一级而不是目录本身因为多数工具默认会在其下找platform-tools\adb.exe。3. adb 服务端起不来5037 端口、版本冲突与设备状态机adb devices敲下去返回空列表是所有问题的起点但它底下藏着至少四种完全不同的故障服务端没起来、服务端起错了版本、设备没被 USB 层识别、设备识别了但没授权。这四种的处理方式完全不一样混在一起排查只会浪费时间。3.1 一个 adb.exe两个进程执行的每条 adb 命令都会先看一眼本机 5037 端口上有没有服务端在跑。没有就 fork 一个出来有就直接连上去。这个服务端是个常驻进程多久退出取决于机器上的其他 adb 命令——只要还有活跃连接它就不退空闲一段时间后才自己收工。这个机制解释了为什么我明明换了新的 adb.exe怎么还是报旧版本号旧的服务端还在后台跑着新客户端连上去就被拒了。REM 显式启动服务端并确认版本 adb start-server adb version REM 看谁占着 5037PID 记下来后可以对着任务管理器查 netstat -ano | findstr :5037 REM 确认是新旧版本打架时先把旧服务端干掉再重来 adb kill-server adb devices -lstart-server失败时通常会打印一行错误别跳过。netstat那步是关键如果 5037 被一个不是 adb 的进程占着——某些同步工具、手机助手、模拟器都会抢这个端口——adb start-server会失败或者连到别人身上去表现为adb devices一直空或者报协议错误。记下 PID在任务管理器里对一下进程名和路径就知道是不是自己的老版本在作怪。adb devices -l比不带参数多输出两列product、model、device。工装机上插着多台设备时这三列是区分设备的唯一可靠依据光看序列号容易认错。3.2 多版本共存时的处置顺序机器上同时有新旧两套 platform-tools 是常态尤其是装过完整 SDK 又单独下了一个老包的机器。处置原则就一条同一时刻只让一个版本当服务端。REM 先看 PATH 里排第一的是哪个 adb where adb REM 用绝对路径调用绕开 PATH 顺序的不确定性 C:\pt22\platform-tools\adb.exe kill-server C:\pt22\platform-tools\adb.exe start-server C:\pt22\platform-tools\adb.exe devices -lwhere adb会按 PATH 顺序把所有匹配项列出来第一行就是命令行实际执行的那个。如果第一行不是你想要的版本要么调整 PATH 顺序要么在脚本里一律用绝对路径——后者我强烈推荐尤其是自动化场景PATH 被别的软件改掉是常有的事脚本里写绝对路径能省掉一整类玄学问题。还有一个坑kill-server只能杀掉当前这个adb.exe逻辑上的服务端如果服务端是被另一个路径下的adb.exe启动的用这个路径去 kill 未必生效。稳妥做法是先taskkill /F /IM adb.exe全清再用目标路径重启。这一步会连带杀掉所有依赖 adb 的进程连接工位上正在跑测试的时候别这么干。3.3 设备状态机offline、unauthorized、device 各说明什么adb devices第一列是序列号第二列是状态。状态值就那么几个但每一个的处置方式完全不同记住这张表能省很多时间。状态含义常见原因处置方向device正常可用—直接执行命令offline端口连上了但握手没完成服务端版本不匹配、USB 线劣质、供电不足kill-server 重来换线换口unauthorized设备未确认本机 RSA 指纹首次连接未点允许或密钥失效看设备屏幕点允许或删%USERPROFILE%\.android\adbdkeyrecovery处于 recovery 模式手动进入视需求决定是否重启回系统sideloadrecovery 下的 sideload 模式手动进入配合adb sideload使用空列表USB 层就没认到驱动缺失、线只有充电功能、USB 调试没开查设备管理器unauthorized在老版本上有个额外变数部分老构建对 RSA 授权的支持不完整接新系统设备时可能反复弹授权框或者一直卡在 unauthorized。这种情况下换新一点的构建反而更省事——这说明老版本不是万能的得看对接的设备是哪一代。offline是最容易被误判成设备坏了的状态。我的经验是先adb kill-server再重来还不行就换一根确定能传数据的线再不行换主机后面的 USB 口前面板的口供电常常不够。这三步能解决绝大多数 offline。状态正常之后的常用操作参数上有些细节值得记一下REM -s 指定序列号多设备时必加单设备时可省略 adb -s serial shell getprop ro.build.version.release REM -r 覆盖安装保留数据-d 允许降级安装 adb -s serial install -r app.apk REM 先清空日志缓冲再复现问题抓到的日志才干净 adb -s serial logcat -c adb -s serial logcat -v time .\log\run.log REM 拉文件时目标写成目录别写文件名避免路径拼接出错 adb -s serial pull /sdcard/crash/ .\log\install -r的-r是 replace existing application不保留的话会失败提示已存在-d是 allow version code downgrade工装机上刷老版本 APK 时经常需要。logcat -c清缓冲这一步很多人省掉结果日志里混着上一次运行的残留排查时对不上时间点。pull的目标参数建议统一写成目录加结尾反斜杠写成文件名时如果本地已存在同名目录行为会很难预期。4. fastboot 通路bootloader 下的另一套驱动与分区刷写adb 通了不代表 fastboot 通。设备重启进 bootloader 之后操作系统不再加载USB 层面暴露出来的是另一个接口Windows 需要另外一套驱动去匹配它。这就是为什么很多机器上adb devices一切都好fastboot devices死活是空的——不是命令的问题是驱动没给 bootloader 接口装上。4.1 两套驱动的差别与手动安装设备在正常系统里USB 描述符通常表现为复合设备Windows 匹配到的是 ADB 接口驱动进了 bootloader暴露的是一个引导器接口VID/PID 都可能变系统找不到匹配项就在设备管理器里挂一个黄色感叹号名字多半是未知设备或者带 Android Bootloader 字样。老包里如果带了usb_driver目录里面那份android_winusb.inf一般同时包含两段安装节一段给 ADB 接口一段给 Bootloader 接口可以一次性把两种模式都覆盖到。手动安装的路径是设备管理器里右键那个带感叹号的设备 → 更新驱动程序 → 浏览计算机 → 让我从列表中选择 → 从磁盘安装 → 指向那个 inf 文件。安装过程中 Windows 会弹一到两次驱动签名确认老 inf 没有现代签名必须点仍然安装否则装不上。REM bootloader 模式下确认通路 fastboot devices fastboot getvar all 21 | findstr /i version product serial REM 如果 devices 一直空先确认设备是不是真在 bootloader adb devices adb reboot bootloaderfastboot devices的输出比 adb 简洁得多就序列号加一个fastboot字样没有 -l 那种详情。getvar all是老版本里信息最全的一条命令能吐出分区表、版本、解锁状态、当前槽位等一大堆东西第一次接触一台陌生设备时我必跑一遍把输出存成文件备查。注意它有些实现会把信息打到 stderr所以要21重定向否则管道接不到。4.2 刷写命令与参数的实际含义刷写类命令看着简单参数错一个字后果就是设备变砖。下面这几条是工位上用得最多的。REM 查解锁状态不同厂商的变量名不一样先 getvar all 里翻 fastboot oem device-info REM 刷单个分区分区名必须与 getvar all 里列出的完全一致 fastboot flash boot boot.img REM 带槽位的设备A/B 分区必须显式指定槽位 fastboot flash boot_a boot.img fastboot --set-activea REM 全部刷完后重启别直接拔线 fastboot rebootfastboot flash的第一个参数是分区名不是文件名也不是镜像类型名。老固件的分区表里可能是boot、recovery、system、userdata新一点的设备会变成boot_a/boot_b这种带槽位后缀的。名字写错时 fastboot 通常会直接报unknown partition并中止算是好事怕的是名字碰巧存在但内容不对那就直接刷废了。所以每次刷之前getvar all的输出必须对着看一遍。--set-activea是切换活动槽位只在 A/B 设备上有意义。老设备上执行会报不支持不影响。4.3 刷写前的核对与卡住时的观测点刷写失败最典型的现象是卡在sending boot (xxxx KB)...这一行不动。这时候先别 CtrlC也别拔线。判断顺序是等够三十秒看设备屏幕有没有进度看 USB 是不是掉过设备管理器里设备消失又出现。如果确实卡死按住电源键强制断电是最低风险的退出方式比拔线安全——拔线时正在写分区最危险。刷写前我固定做三件事。第一确认镜像文件的哈希尤其是从别人那里拷来的第二确认设备电量大半以上刷到一半没电是真正的灾难第三确认现在刷的分区和设备型号匹配型号可以从getvar all里的 product 字段读到。这三件事加起来不到两分钟但能挡掉绝大多数后悔药场景。分区名和镜像的对应关系上容易搞错的有这么几组分区名常见镜像刷错的后果bootboot.img无法启动通常可恢复recoveryrecovery.img进不了恢复模式系统可能仍正常systemsystem.img系统分区损坏必须重刷userdatauserdata.img用户数据全清不可逆bootloaderbootloader.img风险最高失败可能无法进 fastbootuserdata和bootloader这两个要格外小心。前者一刷数据就没了工装机上往往存着标定参数后者刷坏以后可能连 fastboot 都进不去只能靠厂商的底层救砖工具。我一般在这两个操作前会先把getvar all的输出和当前分区备份存一份出事时至少有对照。5. 避坑r22 在 Windows 上最容易翻车的五件事这一节是踩出来的。每一条我都至少遇到过一次写法按现象 → 原因 → 解决来方便对照。5.1 设备管理器黄色感叹号adb devices 永远空现象插上设备设备管理器里某个条目带黄色感叹号adb devices输出List of devices attached之后什么都没有。原因Windows 没匹配到合适的 USB 驱动。老系统上这个问题尤其普遍因为系统自带的驱动库更新不到那么新的 VID/PID 组合而设备厂商又没有提供通用驱动。还有一种情况是之前装过别的手机助手类软件它抢先注册了一个不匹配的驱动把设备挂到了错误的位置。解决先在设备管理器里找到那个感叹号设备看属性里的硬件 ID确认 VID/PID然后用包内usb_driver目录下的 inf 手动指定安装装完拔插一次adb kill-server后重试。如果还是不行去查看 → 显示隐藏的设备把历史遗留的 Android 相关设备全部卸载勾选删除驱动软件再重装一遍干净重来往往比修修补补快。5.2 adb server version doesnt match this client现象任何 adb 命令都返回一行版本不匹配的英文错误然后什么都不做。原因后台已经有一个别的版本的 adb 服务端占着 5037 端口当前执行的客户端连上去对不上版本号。解决taskkill /F /IM adb.exe全清然后用目标版本的绝对路径adb start-server再执行命令。根治办法是机器上只保留一套 platform-tools 在 PATH 里其他版本一律用绝对路径调用脚本里也照此办理。这条我吃过不止一次亏尤其是在装了完整 SDK 又单独丢了老包的机器上。5.3 杀毒软件把 adb.exe 静默隔离现象昨天还好好的今天adb命令报不是内部或外部命令去目录里一看adb.exe没了其他文件都在。原因adb 的端口转发和设备控制行为触发了启发式规则被安全软件判定为风险程序并隔离。静默隔离时通常不给明显提示只在日志里留一条。解决去安全软件的隔离区恢复文件并把整个 platform-tools 目录加进信任列表。工装机上最好在部署阶段就把这条做掉别等到生产时才发现。另外建议每次部署完算一次目录内所有文件的哈希存着文件凭空消失时能第一时间定位是哪个被吃了。5.4 中文路径或超长路径导致 push/pull 失败现象adb push报failed to copy或者adb pull拉到一半中断报错信息很模糊看不出跟路径有关。原因一是工具链对非 ASCII 路径处理不完善二是 Windows 默认路径长度限制在 260 字符深层目录加上长文件名很容易越界。解决工具目录固定用短英文路径C:\pt22工作目录也不要放在桌面或者深层的中文目录下临时建一个C:\work专门放推拉文件。这条改起来最简单但不知道的时候能查半天。5.5 fastboot flash 卡在 sending 不动现象命令停在sending boot (8192 KB)...超过一分钟没动静设备屏幕也没反应。原因可能是 USB 供电或线材问题导致传输中断也可能是镜像本身损坏导致设备端校验失败后没有回包还可能是 bootloader 版本太老不认这个镜像格式。解决等满三十秒确认真卡住长按电源键强制断电退出不要直接拔线。然后依次换线、换主机后置 USB 口、重新校验镜像哈希。如果换了两根线两个口都一样大概率是镜像与 bootloader 版本不匹配这时候要回头确认镜像来源而不是继续试。6. 进阶把 r22 钉进脚本并加上版本巡检工装机上最怕的不是连不上是今天能连明天不能。我的做法是把这个包当成一个受管控的运行时而不是随手解压的一堆文件目录固定、版本固定、调用路径固定再加一层巡检脚本兜底。echo off REM adb22.bat —— 固定走 r22绕开 PATH 顺序问题 setlocal set PTC:\pt22\platform-tools set ADB%PT%\adb.exe if not exist %ADB% ( echo [FAIL] adb not found at %PT% exit /b 1 ) REM 版本巡检读 source.properties比解析 adb version 输出稳 for /f tokens2 delims %%v in (findstr /b Pkg.Revision %PT%\source.properties) do set REV%%v echo [INFO] platform-tools revision %REV% %ADB% start-server nul 21 %ADB% devices -l if errorlevel 1 ( echo [FAIL] adb server start failed exit /b 2 ) REM 回环验证推一个空文件再拉回来能过才算真通 echo probe %TEMP%\pt_probe.txt %ADB% push %TEMP%\pt_probe.txt /data/local/tmp/pt_probe.txt %ADB% pull /data/local/tmp/pt_probe.txt %TEMP%\pt_probe_back.txt %ADB% shell rm -f /data/local/tmp/pt_probe.txt echo [OK] round-trip passed endlocal这个脚本里有三个设计取舍值得说。第一版本号从source.properties读而不是跑adb version因为后者输出格式在不同构建之间会变前者是稳定的键值对。第二start-server的输出重定向到 nul避免它在正常流程里刷屏但 errorlevel 要接住起不来就明确失败退出不要往下走。第三最后那段推拉回环是整段脚本里最有价值的部分——adb devices能列出设备只说明握手成功真正传一次数据才能暴露 DLL 缺失、USB 供电不足、存储权限这些藏在后面的问题。这三步全过我才会认为这台机器的 adb 通路是好的。配合这份脚本我还会在部署时生成一份文件清单快照把adb.exe、fastboot.exe和两个 DLL 的哈希存下来。以后怀疑包被换过或者被安全软件动过直接比对不用猜。# 生成部署快照出问题时用来比对 Get-ChildItem C:\pt22\platform-tools -File | Get-FileHash -Algorithm SHA256 | Select-Object Hash, Path | Export-Csv C:\pt22\snapshot.csv -NoTypeInformation -Encoding UTF8Export-Csv那行加-Encoding UTF8是必要的默认编码在部分中文系统上会把路径写坏回读时对不上。版本策略上还有个经验把 r22 当成一个针对特定设备代的工具而不是通用 adb。新设备接入时先用新构建试新构建不认再退回 r22而不是反过来。反过来做的话一旦某台新设备在 r22 上出现莫名其妙的握手失败很容易被误判成硬件问题白折腾一整天。从那以后我每次交付带 adb 的工装机器都会强制走一遍四步版本巡检、devices -l、推拉回环、fastboot devices四步全过才在交付单上签字。这套流程救过我至少三次——其中一次是安全软件在部署完成后第二天吃掉了AdbWinUsbApi.dll没有回环测试根本发现不了直到产线开线才炸。包认准platform-tools_r22-windows.zip这个全名解压后核对source.properties里的 revision别用来路不明的改名重打包版本。希望帮到你。本文还有配套的精品资源点击获取