ADB命令实战手册:从原理到自动化,Android调试核心技巧
1. 项目概述:为什么我们需要一份自己的ADB命令手册
如果你是一名Android开发者、测试工程师,或者是一个喜欢折腾手机、搞机刷机的极客,那么“adb”这个词对你来说一定不陌生。ADB,全称Android Debug Bridge,中文常译为“安卓调试桥”,是Google官方提供的一个功能极其强大的命令行工具。它就像一把连接电脑和Android设备的“瑞士军刀”,能让你在电脑上通过命令行,直接对手机进行安装应用、传输文件、执行Shell命令、抓取日志、甚至修改系统分区等深度操作。
网络上关于ADB命令的文章和“速查表”多如牛毛,但很多要么过于零散,只列出命令本身;要么过于陈旧,没有涵盖新版本Android的特性;要么就是缺乏上下文,只告诉你“输入这个”,却不解释“为什么用这个”以及“用的时候可能会遇到什么坑”。对于每天都要和ADB打交道的从业者来说,一份真正好用、有深度、有“灵魂”的命令总结,不应该只是简单的罗列,而应该是一份融合了原理、场景、避坑指南和实战心得的“内功心法”。
这份总结的目的,就是帮你构建这样一套心法。我们不追求命令数量上的“大而全”,而是聚焦于那些在开发、测试、逆向、自动化等真实工作流中,最高频、最核心、也最容易出问题的“常用命令”。我会结合自己多年在移动端一线的实战经验,不仅告诉你命令怎么写,更会拆解其背后的工作原理,分享在不同场景下的最佳实践,以及那些官方文档里不会写的“血泪教训”。无论你是刚接触ADB的新手,还是想梳理自己知识体系的老手,这篇文章都能为你提供一个清晰、可靠、可直接投入使用的参考框架。
2. ADB核心架构与工作原理拆解
在开始罗列命令之前,我们必须先理解ADB是怎么工作的。知其然更要知其所以然,这能帮助你在命令失败时,快速定位问题是出在连接、权限还是设备状态上,而不是盲目地重启电脑或设备。
2.1 ADB的三层组件模型
ADB并非一个单一的程序,而是一个客户端-服务器架构的系统,主要包含三个部分:
- ADB Client(客户端):这就是你在电脑命令行中输入的
adb命令本身。它负责接收你的指令,并将其发送给ADB Server。 - ADB Server(守护进程):这是一个在电脑后台运行的守护进程。当你第一次执行任何adb命令时,它会自动启动。它的核心职责是管理客户端与所有已连接Android设备(或模拟器)之间的通信。你可以通过
adb start-server手动启动,或adb kill-server停止它。很多连接问题,通过重启Server就能解决。 - ADB Daemon(adbd,设备端守护进程):这是一个运行在Android设备(或模拟器)后台的守护进程。它以后台服务的形式存在,监听来自ADB Server的连接请求,并执行接收到的命令。在设备的开发者选项中开启“USB调试”,本质上就是激活了这个adbd进程。
当你输入adb devices时,信息流是这样的:Client -> Server -> 通过USB或网络连接到所有设备的adbd -> 收集设备信息 -> 返回给Server -> 显示在Client的终端上。
2.2 连接方式:USB与网络调试
- USB调试:最传统、最稳定的方式。需要USB数据线(请务必使用质量可靠的数据线,劣质线是无数问题的根源),并在设备上开启“开发者选项”中的“USB调试”。连接后,设备通常会弹窗请求“允许USB调试”,务必勾选“始终允许”以避免每次连接都弹窗。
- 网络/Wi-Fi调试:无需数据线,通过TCP/IP网络连接。这非常适合需要频繁插拔或无线测试的场景。设置步骤如下:
- 确保设备和电脑在同一局域网。
- 先用USB连接设备,执行
adb tcpip 5555(5555是默认端口)。这个命令会重启设备上的adbd并监听5555端口。 - 拔掉USB线。
- 获取设备的IP地址(通常在设置-关于手机-状态信息里),执行
adb connect <设备IP>:5555。 - 连接成功后,即可像USB一样操作。
注意:网络调试的稳定性依赖于Wi-Fi网络质量。在自动化测试等对稳定性要求高的场景,USB仍是首选。此外,Android 11及以上版本对无线调试增加了配对码机制,需使用
adb pair <IP>:<端口>并输入屏幕上显示的配对码,然后再adb connect。
2.3 核心概念:Shell与权限层级
通过adb shell命令,你可以进入设备的Linux Shell环境。在这里,你可以执行几乎所有的Linux命令(如ls,cd,cat,ps等)。但关键点在于权限:
- 非root Shell (
$):这是普通用户权限。你只能访问应用沙盒和数据分区(/data/data/)中属于当前用户的应用数据,无法访问系统分区或修改系统设置。 - root Shell (
#):这是超级用户权限。可以访问和修改整个文件系统,包括只读的/system分区。要获得root权限,通常需要设备已解锁Bootloader并刷入了Magisk等root管理工具,然后在adb shell中执行su命令。重要提示:绝大多数消费级手机出厂系统无法直接adb root,adb root命令通常仅在自定义ROM或部分工程测试机上有效。
理解这些底层原理,能让你明白为什么有些命令需要root,而有些不需要;为什么有时候连接不上;以及当命令执行失败时,应该从哪个环节开始排查。
3. 设备管理与基础操作命令详解
这是使用ADB的第一步,也是最基础、最常用的一组命令,关乎你能否与设备正常“对话”。
3.1 设备连接与状态查询
adb devices:这是你的“望远镜”。列出当前所有连接到电脑的Android设备和模拟器。输出示例:
List of devices attached emulator-5554 device 9ABCDEF012345678 unauthorized 192.168.1.100:5555 devicedevice:设备已连接且授权调试。unauthorized:设备已连接,但未在手机上点击“允许USB调试”授权。去手机屏幕上点“确定”吧。offline:设备连接异常,adbd进程可能无响应。尝试重插USB、重启adbd或设备。
adb get-state:快速获取指定设备的状态(device,offline,unknown)。adb get-serialno:获取设备的序列号,在有多台设备时用于精确指定目标。
多设备操作:当连接了多台设备时,任何命令都需要通过-s <设备序列号>来指定目标。例如:adb -s emulator-5554 shell。如果不指定,adb会报错error: more than one device/emulator。
3.2 应用包管理核心命令
应用安装、卸载、查看是测试和开发中的日常。
adb install [-lrtsdg] <apk路径>:安装应用。
-l:锁定应用(Forward lock)。-r:覆盖安装,保留数据。这是最常用的参数,用于应用升级测试。-t:允许安装测试APK。-s:安装到SD卡(现在很少用了)。-d:允许版本降级安装。-g:授予APK清单文件中声明的所有运行时权限。Android 6.0 (API 23) 及以上版本必备参数,否则安装后需要手动在设备上点授权。
adb uninstall [-k] <包名>:卸载应用。
<包名>:如com.example.app。如何获取包名?后面会讲。-k:卸载应用但保留数据和缓存目录。这在测试数据清理或特定场景下很有用,但通常我们完全卸载时不加此参数。
adb shell pm list packages [-f] [-d] [-e] [-s] [-3] [-i] [过滤器]:列出应用包名。这是pm(Package Manager) 工具的命令。
-f:显示关联的APK文件路径。-3:只显示第三方应用。-s:只显示系统应用。-i:同时显示安装来源(Installer)。过滤器:可以模糊搜索,如adb shell pm list packages | grep tencent查找腾讯系应用。
实操心得:adb install -r -g是我在自动化测试脚本中的标准安装姿势,确保应用总能获得所需权限。而adb shell pm path <包名>能快速定位一个已安装应用的APK在设备上的具体存放路径(通常在/data/app/...或/system/app/...),对于提取APK进行分析非常有用。
3.3 文件传输与操作
adb push <本地路径> <设备路径>:将电脑文件推送到设备。adb pull <设备路径> [本地路径]:将设备文件拉取到电脑。如果省略本地路径,则拉取到当前命令行目录。
路径注意事项:
- 设备路径如果包含空格,需要用引号括起来,如
adb push "my file.txt" "/sdcard/Download/"。 - 向
/sdcard/(内部存储)或/storage/emulated/0/(同上)推送文件通常不需要root权限。但向/data/local/tmp推送可能需要,这个目录常用于临时存放测试脚本或工具。 - 使用
adb shell进入后,可以用cp,mv,rm,chmod等Linux命令直接操作设备文件,比push/pull更灵活。
常见问题:执行adb push时提示failed to copy ...: Permission denied。这通常是因为目标目录没有写权限。尝试推送到/sdcard/目录下,或者先adb shell进去,用su提权后再用cat或dd命令间接写入。
4. 调试与信息获取命令实战
这部分命令是定位问题、分析应用行为的关键,尤其对于开发和测试人员。
4.1 日志抓取与分析
adb logcat:这是最重要的调试命令,用于查看设备系统日志。但直接使用会信息爆炸。
adb logcat -v time:显示每条日志的详细时间戳。adb logcat -v threadtime:显示时间、进程/线程ID,格式清晰,推荐使用。adb logcat *:W:只显示警告(Warning)及以上级别的日志,过滤掉冗长的Verbose和Debug信息。adb logcat -s TAG:只显示特定标签(TAG)的日志,如adb logcat -s MyApp。adb logcat -c:清空当前的日志缓冲区。adb logcat -d > log.txt:将当前缓冲区中的所有日志导出到电脑的log.txt文件中,然后退出。常用于一次性抓取。
高级用法:按进程过滤。首先通过adb shell ps | grep <包名>找到目标应用的进程ID(PID),例如PID是12345。然后使用adb logcat --pid=12345就可以只抓取该进程的日志,非常纯净。
adb bugreport:生成一个完整的错误报告zip包,包含系统状态、日志、堆栈跟踪等信息。文件较大,但分析复杂系统性问题时是宝藏。生成后会自动拉取到电脑当前目录。
4.2 系统状态与性能监控
adb shell dumpsys:这是一个信息宝库,可以dump出几乎所有系统服务的状态。
adb shell dumpsys activity activities:查看当前Activity栈信息,对于分析页面跳转问题至关重要。adb shell dumpsys meminfo <包名或PID>:查看指定应用的内存使用详情,包括Java堆、Native堆、PSS等。adb shell dumpsys cpuinfo:查看CPU占用情况。adb shell dumpsys battery:查看电池状态,还可以通过adb shell dumpsys battery set level 50模拟电量变化(需要root)。adb shell dumpsys package <包名>:查看某个应用的完整安装信息,包括版本号、权限、组件等。
adb shell top:实时查看进程的CPU和内存占用情况,类似于Linux的top命令。按q退出。
adb shell procrank:查看进程的内存占用排名(VSS, RSS, PSS, USS)。这个命令需要设备有procrank可执行文件,通常需要root权限或工程机。
4.3 输入模拟与事件注入
adb shell input:模拟各种输入事件。
adb shell input text "HelloWorld":在当前焦点输入框输入文本(不支持中文)。adb shell input keyevent <键值>:模拟按键,如KEYCODE_HOME(3),KEYCODE_BACK(4),KEYCODE_ENTER(66)。可以通过adb shell input keyevent 3模拟按下Home键。adb shell input tap <x> <y>:在屏幕坐标(x, y)处模拟点击。adb shell input swipe <x1> <y1> <x2> <y2> [duration]:从(x1,y1)滑动到(x2,y2),可指定持续时间(毫秒)。
坐标获取:可以通过开发者选项中的“指针位置”功能,在屏幕上实时查看坐标。对于自动化脚本,更可靠的方式是使用UI Automator等工具基于控件属性定位,而非绝对坐标。
adb shell screencap -p /sdcard/screen.png:截取屏幕截图并保存到设备。adb shell screenrecord /sdcard/demo.mp4:录制屏幕(默认最多180秒),按Ctrl+C停止。录制视频对于提交Bug或演示操作流程非常有用。
5. 高级功能与自动化脚本集成
当基础命令玩转后,就可以组合它们,实现一些高级功能和自动化。
5.1 无线调试与端口转发
adb tcpip <端口>:如前所述,将设备监听模式切换到TCP/IP,指定端口。adb connect <主机:端口>:连接网络设备。adb disconnect <主机:端口>:断开网络连接。
adb forward <本地端口> <设备端口>:端口转发。例如adb forward tcp:6100 tcp:7100,将电脑的6100端口数据转发到设备的7100端口。这常用于在电脑上通过本地浏览器调试设备上的WebView内容,或者让电脑上的IDE连接设备上的调试服务。
adb reverse <设备端口> <本地端口>:反向端口转发(Android 5.0+)。将设备端某个端口的请求转发到电脑的端口。这在开发时特别有用,比如设备上的应用需要访问电脑上运行的本地开发服务器(如React Native packager),可以执行adb reverse tcp:8081 tcp:8081。
5.2 Shell命令的进阶用法
直接在adb shell后接命令,可以让命令在设备上执行后立即返回结果到电脑终端,无需进入交互式Shell。例如:
adb shell ls /sdcard/:列出设备sdcard目录。adb shell pm clear <包名>:清空指定应用的所有数据,相当于“恢复出厂设置”该应用。测试数据清理的利器。adb shell am start -n <包名>/<Activity全限定名>:启动一个Activity。例如adb shell am start -n com.android.settings/.Settings。adb shell am force-stop <包名>:强制停止一个应用。
组合技示例:一键清理并重启应用
adb shell pm clear com.example.myapp adb shell am start -n com.example.myapp/.MainActivity这个组合在自动化测试的初始化环节非常常用。
5.3 集成到脚本与自动化流程
ADB命令是Android自动化测试(无论是单元测试、UI测试还是Monkey测试)的基石。它们可以轻松地被集成到Shell脚本、Python脚本或CI/CD(如Jenkins)流水线中。
一个简单的自动化测试片段(Shell脚本):
#!/bin/bash # 1. 连接设备 adb connect 192.168.1.100:5555 # 2. 卸载旧版本(如果存在) adb uninstall com.example.testapp # 3. 安装新APK adb install -r -g app-debug.apk # 4. 授予额外权限(如果需要) adb shell pm grant com.example.testapp android.permission.ACCESS_FINE_LOCATION # 5. 启动应用 adb shell am start -n com.example.testapp/.MainActivity # 6. 等待并抓取日志 sleep 2 adb logcat -d --pid=$(adb shell pidof -s com.example.testapp) > startup.log # 7. 执行Monkey测试 adb shell monkey -p com.example.testapp --throttle 100 -v 500注意事项:在自动化脚本中,务必加入错误检查和重试机制。例如,在执行关键命令后检查其返回值($?在Shell中为上一条命令的退出状态,0表示成功),如果失败则记录日志并尝试恢复操作或退出。
6. 常见问题排查与实战技巧实录
即使命令背得再熟,实战中依然会踩坑。这里记录了一些高频问题和解决思路。
6.1 连接类问题
问题:adb devices显示unauthorized。
- 排查:检查手机屏幕是否有“允许USB调试”的弹窗,点击确认。如果之前点过但无效,尝试在开发者选项里“撤销USB调试授权”,然后重新插拔。
- 进阶:有时是电脑上的RSA密钥指纹不匹配。可以删除电脑用户目录下的
.android/adbkey和.android/adbkey.pub文件(Linux/Mac在~/.android/,Windows在C:\Users\<用户名>\.android\),然后重试。注意:这会清除所有已授权设备的记录。
问题:设备列表为空或反复掉线。
- 排查1 - 数据线:换一根确认能传输数据(不只是充电)的USB线。这是最常见的原因。
- 排查2 - 驱动:在Windows上,确保安装了正确的USB驱动。可以尝试使用Google官方USB驱动,或手机厂商提供的驱动。
- 排查3 - 进程冲突:关闭电脑上可能占用5037端口的程序(如其他Android模拟器、手机助手)。用
netstat -ano | findstr :5037(Windows) 或lsof -i :5037(Mac/Linux) 查看。 - 排查4 - 重启大法:依次尝试
adb kill-server->adb start-server,重启手机,重启电脑。
6.2 命令执行类问题
问题:adb install失败,提示INSTALL_FAILED_INSUFFICIENT_STORAGE。
- 排查:设备存储空间不足。清理设备空间,或使用
adb shell pm trim-caches <大小>(需要root)来清理缓存文件。
问题:adb shell执行某些命令提示Permission denied。
- 分析:权限不足。分两种情况:
- 文件系统权限:尝试操作
/system等受保护目录的文件。需要root权限,先执行su。 - SELinux权限:在较新Android版本上,即使root了,SELinux策略也可能阻止操作。命令提示可能包含
avc: denied。临时关闭SELinux审计(仅限调试,有安全风险):adb shell setenforce 0。查看状态:adb shell getenforce。
- 文件系统权限:尝试操作
问题:logcat看不到自己应用的日志。
- 排查1 - 日志级别:默认是Verbose,可能被其他日志淹没。使用
adb logcat -s YourAppTag或按PID过滤。 - 排查2 - 应用未开启调试:确保应用
AndroidManifest.xml中的<application>标签设置了android:debuggable="true"(Debug构建默认是true,Release构建是false)。 - 排查3 - 缓冲区:有些日志可能写入其他缓冲区(如
events,radio)。尝试adb logcat -b all查看所有缓冲区。
6.3 效率工具与技巧
别名(Alias):在
~/.bashrc或~/.zshrc中为常用命令设置别名,极大提升效率。alias adbd='adb devices' alias adbi='adb install -r -g' alias adbu='adb uninstall' alias adblc='adb logcat -c' alias adbld='adb logcat -d -v threadtime' alias adbs='adb shell'使用
adb wait-for-device:在脚本中,这个命令会阻塞,直到有设备连接上来。可以确保后续命令在设备就绪后才执行。组合命令与管道:利用Shell的管道功能。例如,一键清除所有第三方应用日志:
adb logcat -c && adb shell pm list packages -3 | cut -f 2 -d ":" | xargs -L1 adb shell pm clear(警告:此命令会清空所有第三方应用数据,慎用!)。备份与还原(已弃用但需了解):
adb backup和adb restore命令在较新Android版本中已基本失效,不应再作为主要备份手段。应用数据备份应考虑各应用自带的云同步或使用需要root权限的第三方工具(如Titanium Backup)。
掌握ADB,不仅仅是记住命令,更是理解Android系统与外界交互的桥梁。从简单的文件传输到复杂的系统调试,从手动操作到自动化脚本,这套工具链的熟练度,直接体现了你对Android平台的理解深度和问题解决效率。希望这份融合了原理与实战的总结,能成为你手边常备的利器,让开发和调试工作更加得心应手。
