你手机屏幕碎了想导出相册里的照片,或者在做安卓开发时想抓取崩溃日志,又或者只是想给手头的安卓盒子装个软件却找不到合适的遥控器操作方式——这些场景里,ADB 都是那个能真正救你一把的工具。ADB 的全称是 Android Debug Bridge,翻译过来就是“安卓调试桥”,它是安卓官方提供的一套命令行调试工具,本质上是电脑与安卓设备之间的一座通信桥梁。无论你是开发者、测试工程师、玩机爱好者,还是单纯想折腾一下自己的安卓设备,这套工具都值得花点时间掌握。这篇内容会从环境搭建讲起,一路覆盖高频命令、系统级操作、自动化脚本和实战排查,目标是让你看完就能上手,遇到问题也能自己排查。
1. 认识 ADB:它到底能做什么
1.1 ADB 的架构与工作方式
ADB 不是一个孤立的程序,它由三个部分组成:运行在电脑上的客户端、运行在电脑后台的服务端,以及运行在安卓设备上的守护进程。客户端是你在命令行里敲下的 adb 命令,服务端负责管理客户端与设备之间的通信,守护进程 daemon 则常驻在设备系统中,负责接收电脑端发来的指令并执行。
这三个角色的协作模式可以这样理解:就像你去餐厅吃饭,客户端是拿着菜单点菜的你,服务端是记录订单的后厨调度员,而守护进程则是厨房里真正动手做菜的厨师。你只管告诉调度员你要什么,调度员把需求传达给厨师,厨师把“菜”做好后原路端回给你。
这种架构带来的直接好处是稳定和统一。不管你的安卓设备是通过 USB 线连接、Wi-Fi 无线连接,还是通过网络端口连接,电脑端的命令入口都是一样的。对于使用者来说,这意味着你只需要掌握一套命令语法,就能应对几乎所有连接方式。
注意:ADB 服务端启动后常驻后台,占用端口 5037。实际使用中如果出现“端口被占用”的报错,很多时候就是有另一个 adb 进程没有正确退出导致的。
理解了这套架构,后面排查问题时思路会清晰很多。比如当你遇到“device offline”提示时,问题往往出在守护进程与电脑端的连接不稳定,而不是命令本身写错了。
1.2 环境准备:下载与安装配置
开始使用 ADB 之前,你需要准备好工具和环境。ADB 并不是单独发布的软件包,而是包含在安卓官方提供的 Platform Tools 里。这套工具包里除了 adb,还有 fastboot、systrace 等辅助工具。无论你用的是 Windows、macOS 还是 Linux,都建议直接下载对应平台的 Platform Tools。
下载之后,强烈建议做一步操作:把 adb 所在的目录配置到系统的环境变量里。以 Windows 为例,解压 platform-tools 后,你可以在系统属性里找到“环境变量”,然后在 Path 中加入该目录的完整路径。这样做的好处是,以后在任何目录下打开命令行都能直接敲 adb 命令,不用每次切换路径。
macOS 和 Linux 下同理,把路径写入 shell 配置文件即可。比如可以在 ~/.zshrc 或 ~/.bashrc 末尾追加一行export PATH=$PATH:/你的路径/platform-tools,然后执行source ~/.zshrc让配置立刻生效。
安装配置好之后,打开终端输入adb version,如果能看到版本号输出,说明环境已经就绪。我在实际配置中遇到过最常见的问题,是明明已经配置了环境变量,但新开的终端窗口仍然提示找不到命令——这是因为环境变量的修改只对新启动的终端生效,已经打开的终端窗口需要关掉重开,或者手动执行刷新命令才能识别到新配置。
另一个容易踩的坑是驱动问题。Windows 系统下,如果设备管理器里看不到你的安卓设备,或者设备名称旁边有一个黄色感叹号,说明驱动没有正确安装。多数情况下,安装设备厂商提供的 USB 驱动可以解决;如果没有合适的驱动,也可以尝试在设备管理器里手动更新驱动,选择“浏览我的电脑查找驱动”,然后定位到 platform-tools 目录下的驱动文件夹。
2. 连接设备与基础命令实操
2.1 USB 连接与无线连接的正确姿势
连接安卓设备,第一步是在手机上打开开发者选项。Android 系统默认隐藏了这个入口,你需要进入“关于手机”,连续点击“版本号”七次左右,系统会提示已进入开发者模式。然后回到设置主界面,找到开发者选项,打开“USB 调试”开关。
用数据线把设备连接到电脑后,第一次执行adb devices时,手机屏幕上通常会弹出“是否允许 USB 调试”的授权对话框,你需要点击允许并勾选“始终允许使用这台计算机进行调试”。这个授权机制是安全设计的一部分,避免其他连接过你电脑的人随意操作你的设备。
完成之后再次执行adb devices,如果看到类似emulator-5554 device或者xxxxx device的输出,说明连接成功。这里有个细节值得注意:adb devices的输出中,设备状态分为device、offline、unauthorized三种。device表示一切正常,offline表示设备在线但通信异常,unauthorized表示设备没有授权电脑的调试请求。
除了 USB 连接,Android 11 及以上版本还支持无线调试功能。开启无线调试后,执行adb pair 手机IP地址:端口号,再输入配对码完成配对,最后执行adb connect 手机IP地址:端口号建立连接。配对过程中,手机端会显示一个六位数的配对码,需要你在电脑端输入。这种方式的实用场景是:手机和电脑在同一个局域网内,不想总是插拔数据线,或者 USB 接口不太稳定的时候。
对于 Android 10 及以下版本的系统,无线连接需要通过一根数据线作为中介。先用 USB 连接设备,执行adb tcpip 5555让设备开启 TCP 监听端口,然后拔掉数据线,执行adb connect 设备IP:5555。注意执行adb tcpip后,USB 连接会断开,这时候再执行adb connect才能通过无线方式建立连接。
2.2 高频基础命令:安装、卸载、传输与重启
连接好设备之后,有几个命令你会频繁用到,而且这几个命令是整个工具链的地基。
安装应用使用adb install,卸载使用adb uninstall。安装命令的标准用法是adb install 包名.apk,也就是把电脑上一个 apk 文件的完整路径传给命令。安装成功后终端会输出Success。如果设备上已经安装了同一个应用,且签名相同,可以加-r参数实现覆盖安装,即adb install -r 应用.apk。如果是测试版应用想快速降级,需要配合-d参数,允许版本号低于当前版本的应用被安装。
卸载命令稍微有点特殊:adb uninstall 包名,这里的参数不是应用名称,而是应用的包名。怎么查包名?后面讲应用管理的时候会详细展开。这里先提一个技巧,如果你正在调试的应用允许备份数据,可以用adb uninstall -k 包名保留数据和缓存目录再卸载,这在进行数据迁移类测试时很实用。
文件传输命令adb push和adb pull也是日常高频率使用的操作。adb push 电脑路径 设备路径是把文件从电脑推送到设备,adb pull 设备路径 电脑路径是把文件从设备拉取到电脑。平时我在排查问题的时候,最喜欢用的操作之一就是adb pull /sdcard/Download/xxx.log ./,把设备里生成的日志文件拉到当前目录来分析。需要注意,设备端的路径如果是/sdcard/或者/storage/emulated/0/,这些是公共存储区域,不需要 root 权限就能读写;但如果是/data/目录下的内容,普通权限下会提示 Permission denied。
重启设备用的是adb reboot,重启到引导加载器模式用adb reboot bootloader,也就是俗称的 fastboot 模式;重启到恢复模式用adb reboot recovery。这三种重启方式的差异在不同品牌的设备上表现不太一样,部分机型会屏蔽某些模式的入口,如果你发现执行后设备卡在某个界面不动,大概率是系统层面的定制限制,不是命令写错了。
这些命令单独看起来都很简单,但组合起来就能做很多事情。比如我想把电脑上一批几百张照片一次性传到手机的 DCIM 目录,可以先adb push整个文件夹进去;想验证某个 APK 安装包能不能正常安装,一条adb install就能搞定,比用手机文件管理器点来点去快得多。
提示:
adb install不支持覆盖安装签名不一致的应用。如果遇到INSTALL_FAILED_UPDATE_INCOMPATIBLE错误,说明设备上已安装的应用签名与当前 APK 签名不一致,需要先卸载旧应用再安装。
3. 精进之路:命令组合与系统级操作
3.1 应用管理的高级操作
掌握了基础命令之后,你会发现 ADB 的价值远不止装装应用、传传文件。通过adb shell进入设备系统环境后,你可以调用安卓系统内部的命令行工具,这些工具能做的事情远超普通用户界面能提供的范围。
以pm命令为例,pm 是 Package Manager 的缩写,负责管理设备上安装的所有应用。pm list packages可以列出全部应用包名,配合grep过滤,可以快速找到某个应用的完整包名。例如pm list packages | grep 某关键词就能筛出包含该关键词的包名。pm path 包名可以显示某个应用安装文件的实际存放路径,这在分析应用来源时非常有用。pm clear 包名可以一键清空应用的所有数据,效果等同于在系统设置里点“清除存储空间”,但速度更快,而且能批量操作。
还有一个容易被低估的命令是pm disable-user 包名,它可以禁用掉一些系统内置且用户无法直接卸载的应用。我在实操中发现,很多安卓电视盒子出厂预装了一堆用不到的应用,这些应用会占用系统资源并启动后台进程。通过pm disable-user禁用它们,可以有效提升设备的流畅度,而且不需要越狱。如果你后续想恢复,执行pm enable 包名即可重新启用。
再来看am命令,am 是 Activity Manager 的缩写,专门管理应用的活动和进程。am start -n 包名/活动名可以直接启动指定应用的某个界面,这在自动化测试中非常常用。比如我想直接打开某个应用的设置页面,只需要知道它的包名和对应的活动名,一条命令就能跳过去。am force-stop 包名可以强制停止某个应用,效果等同于在后台任务列表里划掉应用,但更彻底,会直接终止应用的所有进程。
这些命令组合起来,可以完成一个完整的应用状态流转测试:安装应用、清除数据、启动应用、强制停止应用、再看数据是否重新生成。这套流程我平时用来验证应用在“冷启动”和“热启动”两种状态下的行为是否符合预期。
3.2 系统信息查询与截屏录屏
排查问题的时候,拿到足够的系统信息是第一步。adb shell dumpsys是这套工具链里信息密度最高的命令,它会把系统中各种服务运行状态输出到终端。比较常用的有dumpsys package 包名查看指定应用的所有安装信息,dumpsys activity activities查看当前前台运行的界面栈,dumpsys battery查看电池状态和耗电统计。
getprop命令用来读取系统属性和配置信息,比如getprop ro.product.model可以拿到设备机型名称,getprop ro.build.version.release可以拿到安卓系统版本号。在测试兼容性的时候,我经常让测试设备跑一遍这几个命令,把信息记录下来作为环境参数存档。如果你想看系统里所有支持的命令,在adb shell环境下输入ls /system/bin或ls /system/xbin,会看到一长串可用的工具,这里面有不少是开发者专属的利器。
截屏和录屏也是常用的调试手段。adb exec-out screencap -p > 截图.png可以截取当前屏幕并直接保存到电脑上,adb exec-out screenrecord --bit-rate 4M --time-limit 30 /sdcard/录像.mp4可以录制 30 秒的高清视频。这里的exec-out比较特殊,它告诉 ADB 直接从设备端输出原始数据流,适合处理二进制文件。如果不加exec-out,直接执行adb shell screencap /sdcard/截屏.png则是把截图保存在设备上,然后再用adb pull拉取出来。
提示:执行
screencap或screenrecord前,应用权限里需要允许存储权限,否则文件写入公共目录时可能被拒绝。另外,如果设备上开了屏幕密码锁,截屏时会提示“无法截取安全屏幕”之类的信息,这是系统的安全机制在起作用。
3.3 端口转发与反向转发
端口转发是 ADB 的高级功能,但它往往被初学者忽略。adb forward tcp:电脑端口 设备端口可以把电脑上某个 TCP 端口的所有流量转发到设备上对应的端口。举个例子,设备上跑了一个 HTTP 服务监听 8080 端口,我在电脑上执行adb forward tcp:8080 tcp:8080,然后直接用浏览器访问电脑本机的 8080 端口,就能访问到设备上的服务。
与 forward 对应的反向转发是adb reverse,作用正好相反:把设备上的端口流量转发到电脑上。这在调试 WebView 页面时特别有用。如果开发环境里在电脑上启动了一个本地开发服务器监听 3000 端口,设备上的 WebView 应用想访问这个服务器,正常情况下设备无法直接访问电脑本机的 localhost。执行adb reverse tcp:3000 tcp:3000之后,设备上所有访问 localhost:3000 的请求都会被转发到电脑的 3000 端口,开发调试效率一下子提升不少。
这个功能最常见的应用场景是混合应用的调试,以 Android WebView 为壳的应用,网页资源同时存在本地和远程两种加载方式。有了adb reverse,可以摆脱真机与电脑不同网段的烦恼,直接在设备上访问电脑的本地服务,省去搭服务器或者内网穿透的麻烦。
端口转发有一些使用限制需要留意:转发规则在设备断开连接后会失效,重新连接需要再次设置;同一时间一个端口只能建立一个转发规则,重复设置会覆盖旧的规则。
4. 自动化与脚本化:把 ADB 玩出花
4.1 批量命令与多设备管理
当设备数量多起来之后,逐条敲命令显然不现实。ADB 提供了-s参数来指定设备序列号,这样可以在多台设备同时连接的情况下,精准操作其中某一台。先执行adb devices查看所有连接的设备序列号,然后在每条命令里带上-s 设备序列号即可。多台设备并行操作的场景在自动化测试中很常见,比如一个测试任务需要在十台不同的设备上跑,就可以写一个循环脚本,依次对每台设备执行相同的命令。
一个简单的示例脚本,在 Windows 批处理环境下可以这样写:
@echo off for /f "skip=1 tokens=1" %%i in ('adb devices') do ( echo 正在操作设备 %%i adb -s %%i install test.apk )这段脚本的逻辑是:执行adb devices获取设备列表,跳过第一行表头,把每一行的第一个字段即设备序列号取出来,然后逐个执行安装命令。Linux 或 macOS 下可以用 bash 实现对等操作:
adb devices | awk 'NR>1 && $2=="device" {print $1}' | while read serial; do echo "正在操作设备 $serial" adb -s "$serial" install test.apk done批量命令需要特别注意一个问题:不同设备可能处于不同状态,有的连接正常,有的处于 unauthorized 状态。在脚本里加上$2=="device"这个判断条件,可以过滤掉非正常状态的设备,避免脚本执行时报错。
4.2 配合自动化测试:从手工点击到无人值守
ADB 的价值在自动化领域体现得尤为明显。安卓系统自带一个名为monkey的压力测试工具,可以通过命令行向设备发送随机事件流。执行adb shell monkey -p 包名 --throttle 200 --seed 12345 -v 500,可以让系统对指定应用随机执行 500 次操作,包括点击、滑动、按键等等。如果过程中应用没有崩溃,说明稳定性初步过关;如果发生崩溃,monkey 会把崩溃日志输出到终端,方便定位问题。
--throttle参数表示两次操作之间的延迟毫秒数,避免操作太密集导致响应不过来;--seed参数用于指定随机种子,同样的种子可以复现同样的操作序列,这在回归复测中非常有用。实际使用中,我习惯先跑少量事件比如 100 次,确认随机操作没有触碰敏感功能,再跑大数量的压测。
对于需要精确控制操作的场景,可以使用input命令。adb shell input keyevent 4模拟按下返回键,adb shell input tap x y模拟点击屏幕坐标,adb shell input swipe x1 y1 x2 y2 500模拟滑动操作。这几个命令组合起来,就能模拟出一个“虚拟手指”在屏幕上做各种手势操作。如果你想模拟文本输入,可以执行adb shell input text 要输入的内容,中文内容会出现兼容性问题,但英文和数字基本没问题。
这套组合拳可以完成很多自动化场景,比如自动登录应用、自动滑动浏览、进入某个设置页面、抓取页面信息等。配合系统自带的dumpsys可以验证操作后的结果是否符合预期,再结合 shell 循环逻辑,就能实现一个简单的无人值守测试框架。
4.3 数据备份与批量文件提取
说到数据备份,ADB 提供的adb backup命令可以备份应用的数据到电脑上,adb restore可以恢复备份文件到设备。不过这个命令在新版安卓系统上限制越来越多,部分厂商的设备并不支持完整的备份恢复,次数多了之后你会发现成功率并不稳定。我的建议是不要把adb backup当成唯一的数据安全方案,日常的重要数据仍然需要借助应用自身的云同步或者系统级的备份机制来保障。
批量文件提取方面,adb pull配合 shell 命令可以做到目录级别的整体拉取。比如你想把设备上整个DCIM目录的照片全部备份到电脑,执行adb pull /sdcard/DCIM ./DCIM_备份就能一次搞定。如果只想提取最近修改的文件,可以先在设备端用ls -lt排序找到目标,再决定拉取哪些文件。
我在日常使用中总结了一个经验:不要等到设备快不行了才想起备份。我习惯在设备新拿到手时,先执行一次adb shell getprop ro.product.model和adb shell getprop ro.build.version.release记录设备信息,然后定期把关键目录备份到电脑。这样即便设备出了问题,手上的数据还能保证是最近一次备份的状态。
5. 实战排查:常见问题与解决办法
5.1 连接类问题速查表
| 问题现象 | 可能原因 | 解决办法 |
|---|---|---|
提示unauthorized | 设备未信任当前电脑 | 检查设备端弹出的授权对话框,点击允许并勾选始终允许;重新插拔数据线后再试 |
提示device offline | 设备与电脑连接中断或驱动异常 | 重启 adb 服务,执行adb kill-server再adb start-server;换一条数据线或换一个 USB 接口 |
提示no devices/emulators found | 未开启 USB 调试,或设备未正确识别 | 确认已开启开发者选项和 USB 调试;检查设备管理器里的驱动状态;将连接方式改为“文件传输 MTP”模式再试 |
| adb 命令无响应,卡死 | adb 服务端异常或多进程冲突 | 执行adb kill-server强制结束所有 adb 进程,然后重新启动;必要时重启系统 |
| 无线连接不稳定,频繁掉线 | 局域网信号差或设备休眠 | 调整无线网络环境;在开发者选项里开启“保持唤醒”状态;尝试重启 wifi 后重新配对 |
排查连接类问题的基本思路是:先看adb devices输出,判断设备状态属于哪一类;再根据状态判断问题环节。如果是unauthorized,核心在授权;如果是offline,核心在连接质量;如果是找不到设备,核心在驱动和接口。换个数据线有时候比折腾半天驱动还管用,别看不上这种“土办法”,USB 线质量差导致供电不足、信号干扰、数据传输错乱的情况非常常见,是我排查连接问题时的第一优先级。
5.2 操作类常见报错与解决
INSTALL_FAILED_INSUFFICIENT_STORAGE是安装应用时最常见的一个错误,意思是设备存储空间不足。但在测试机上,这个提示有时候是误导,真正的原因是/data分区确实满了,但你删文件却删不出来。解决方法是进入设置里清理应用缓存,或者用pm clear 包名清空几个不常用应用的数据,腾出空间再安装。
INSTALL_FAILED_UPDATE_INCOMPATIBLE在前文已经提到过,本质上是新旧应用的签名不一致。这个问题在开发环境中尤其容易遇到:同一个应用,从测试环境签名切换到了正式签名,或者安装包由不同构建机生成,导致签名不同。最简单的解决方法就是卸载掉旧版本再安装新版本,但要提醒一句:卸载会清掉这个应用的全部本地数据,需要先备份。
Permission denied错误在执行 shell 命令时比较常见,这说明你尝试访问的文件或目录在当前权限下不可访问。普通权限下,/data、/system等目录是受限的;如果你确实需要读取这些区域的内容,某些情况下可以通过adb root获得 root 权限,但前提是当前设备开启了 root 功能,或者系统是 userdebug 版本。多数量产设备执行adb root会提示adbd cannot run as root in production builds,这是正常现象,说明你的设备不支持通过这种方式获取 root 权限。
执行adb shell进入命令行后,如果命令输出乱码,大多与编码格式有关。Windows 的默认命令行编码与 Linux 字符集不一致会导致中文乱码,可以在执行前先运行chcp 65001把命令行代码页切换为 UTF-8,再执行 adb shell 命令。macOS 和 Linux 下一般不会有这个问题,但如果你在 Linux 下遇到中文乱码,可以在 shell 里执行export LANG=en_US.UTF-8试试。
注意:
adb install命令在部分国产系统定制版本上可能会被安全策略拦截,弹出“禁止安装未知来源应用”的提示。这种情况下用命令行直接安装比较麻烦,推荐手动在设备上打开“允许安装未知应用”的权限后,再使用 adb 安装。
5.3 提升效率的几个小习惯
最后分享几个我自己用下来的习惯。第一个是用别名或函数包装高频命令。我习惯在 shell 配置文件里给常用命令设置缩写,比如alias ai='adb install'、alias aun='adb uninstall'、alias push='adb push'、alias pull='adb pull'。这样在实际操作中能少打很多字符,效率提升明显。
第二个习惯是配合终端多窗口使用。我会开两个终端窗口,一个专门跑adb logcat持续输出日志,另一个执行其他操作。这样在复现 bug 时,日志窗口能实时记录整个过程中系统打印的信息,另一个窗口操作完再回头翻日志,定位问题很快。
第三个习惯是和文件系统联动。ADB 本身是纯命令行工具,但它可以配合电脑上的文件资源管理器一起使用。比如执行adb pull拉取文件时,写好目标目录,拉完直接就在电脑上打开;执行adb push推送文件时,也要提前理清电脑端源文件的存放路径,避免路径太深找不到文件或者在错误目录下执行命令。
第四个习惯是定期执行adb kill-server。我在长时间连着多台设备的时候,偶尔会遇到设备列表不刷新、命令执行超时等情况,先执行adb kill-server再adb start-server,多半能恢复正常。这个操作非常简单,但很多人不知道,其实它暴露的是 ADB 服务端累积的连接状态没有及时清理的问题。
几个实用的一点代码片段也可以提高工作效率。比如批量给设备安装同一个 APK,在 Linux 下可以这样写:
adb devices | awk 'NR>1 && $2=="device" {print $1}' | xargs -i adb -s {} install 你的应用.apk批量清空指定包名的应用数据:
for pkg in com.example.one com.example.two; do adb shell pm clear $pkg done批量获取设备机型信息生成测试报告:
adb devices | awk 'NR>1 && $2=="device" {print $1}' | while read s; do model=$(adb -s $s shell getprop ro.product.model) version=$(adb -s $s shell getprop ro.build.version.release) echo "$s | $model | Android $version" done这一节的内容覆盖了不少实际操作中容易踩的坑。我自己印象最深刻的一次,是调试某个应用时,死活提示INSTALL_FAILED_UPDATE_INCOMPATIBLE,检查了一圈才发现旧版本的应用是用另一个签名证书构建的。折腾了一个小时,最后卸载重新安装,几分钟就解决了。从那以后我养成了一个习惯,每一个待安装的 APK 在推送安装前,先确认它和当前设备上已安装版本是否存在签名差异,避免在签名一致性和安装顺序上浪费时间。
用 ADB 调试设备这件事,说难并不难,命令本身背熟就能应付大部分日常工作;说容易也不容易,因为真正到系统底层操作时,你会碰到各种各样的权限限制、厂商定制和安全机制拦截。但只要你愿意花点时间把基础命令和排查思路掌握扎实,它会成为你手里非常顺手的一套工具。我现在遇到安卓设备相关的问题,第一反应就是用 ADB 去看日志、查系统信息、验证据,而不是盲目地去点击设备界面盲猜。也建议你把这篇文章里的关键命令抄下来,在真正需要的时候拿起来就能用,用多了自然就熟了。