ADB(Android调试桥)
Android 调试桥 (adb) 是一种功能多样的命令行工具,可让您与设备进行通信。adb 命令可用于执行各种设备操作(例如安装和调试应用),并提供对 Unix shell(可用来在设备上运行各种命令)的访问权限。它是一种客户端-服务器程序,包括以下三个组件:
- 客户端:用于发送命令。客户端在开发计算机上运行。您可以通过发出 adb 命令从命令行终端调用客户端。
- 守护程序 (adbd):用于在设备上运行命令。守护程序在每个设备上作为后台进程运行。
- 服务器:用于管理客户端与守护程序之间的通信。服务器在开发机器上作为后台进程运行。
adb
包含在 Android SDK 平台工具软件包中。位于 android_sdk/platform-tools/
下,一般将其路径配置在环境变量下。
adb 的工作原理
当启动某个 adb 客户端时,该客户端会先检查是否有 adb 服务器进程正在运行。如果没有,它会启动服务器进程。服务器在启动后会与本地 TCP 端口 5037 绑定,并监听 adb 客户端发出的命令 - 所有 adb 客户端均通过端口 5037 与 adb 服务器通信。
然后,服务器会与所有正在运行的设备建立连接。它通过扫描 5555 到 5585 之间(该范围供前 16 个模拟器使用)的奇数号端口查找模拟器。服务器一旦发现 adb 守护程序 (adbd),便会与相应的端口建立连接。请注意,每个模拟器都使用一对按顺序排列的端口 - 用于控制台连接的偶数号端口和用于 adb 连接的奇数号端口。例如:
模拟器 1,控制台:5554
模拟器 1,adb:5555
模拟器 2,控制台:5556
模拟器 2,adb:5557
依此类推
如上所示,在端口 5555 处与 adb 连接的模拟器与控制台监听端口为 5554 的模拟器是同一个。
服务器与所有设备均建立连接后,便可以使用 adb 命令访问这些设备。由于服务器管理与设备的连接,并处理来自多个 adb 客户端的命令,因此可以从任意客户端(或从某个脚本)控制任意设备。
通过 WLAN 连接到设备(Android 10 及更低版本)
一般情况下,adb 通过 USB 与设备进行通信,但也可以在以下情况下通过 WLAN 使用 adb:
- 如需连接到搭载 Android 11(及更高版本)的设备,请参阅在硬件设备上运行应用的“WLAN”部分。
- 如要连接到搭载早期 Android 版本的设备,必须通过 USB 执行一些初始步骤。下文对这些步骤做了说明。
- 如果开发的是 Wear OS 应用,请参阅调试 Wear OS 应用指南,其中提供了有关如何通过 WLAN 和蓝牙使用 adb 的特别说明。
-
将 Android 设备和 adb 主机连接到这两者都可以访问的同一 WLAN 网络。请注意,并非所有接入点都适用;可能需要使用防火墙已正确配置为支持 adb 的接入点。
-
如果要连接到 Wear OS 设备,请关闭手机上与该设备配对的蓝牙。
-
使用 USB 线将设备连接到主机。
-
设置目标设备以监听端口 5555 上的 TCP/IP 连接。
adb tcpip 5555
-
拔掉连接目标设备的 USB 线。
-
找到 Android 设备的 IP 地址。例如,对于 Nexus 设备,您可以在设置 > 关于平板电脑(或关于手机)> 状态 > IP 地址下找到 IP 地址。或者,对于 Wear OS 设备,您可以在设置 > WLAN 设置 > 高级 > IP 地址下找到 IP 地址。
-
通过 IP 地址连接到设备。上一步查询的ip地址是(172.23.33.2)
adb connect device_ip_address(172.23.33.2)
-
确认主机已连接到目标设备
adb devices List of devices attached 172.26.33.2:5555 device
如果 adb 连接断开:
-
确保主机仍与 Android 设备连接到同一个 WLAN 网络。
-
通过再次执行
adb connect
步骤重新连接。 -
如果上述操作未解决问题,重置 adb 主机:
adb kill-server
然后,从头开始操作。
查询设备
adb devices -l
作为回应,adb 会针对每个设备输出以下状态信息:
- 序列号:由 adb 创建的字符串,用于通过端口号唯一标识设备。 下面是一个序列号示例:
emulator-5554
- 状态:设备的连接状态可以是以下几项之一:
offline
:设备未连接到 adb 或没有响应。device
:设备现已连接到 adb 服务器。请注意,此状态并不表示 Android 系统已完全启动并可正常运行,因为在设备连接到 adb 时系统仍在启动。不过,在启动后,这将是设备的正常运行状态。no device
:未连接任何设备。
- 说明:如果您包含
-l
选项,devices
命令会告知您设备是什么。当您连接了多个设备时,此信息很有用,可帮助您将它们区分开来。
模拟器未列出
adb devices
命令的极端命令序列会导致正在运行的模拟器不显示在adb devices
输出中(即使在您的桌面上可以看到该模拟器)。当满足以下所有条件时,就会发生这种情况:- adb 服务器未在运行,
- 在使用
emulator
命令时,将-port
或-ports
选项的端口值设为 5554 到 5584 之间的奇数, - 选择的奇数号端口处于空闲状态,因此可以与指定端口号的端口建立连接,或者该端口处于忙碌状态,模拟器切换到了符合第 2 条中要求的另一个端口
- 启动模拟器后才启动 adb 服务器。
避免出现这种情况的一种方法是让模拟器自行选择端口,并且每次运行的模拟器数量不要超过 16 个。另一种方法是始终先启动 adb 服务器,然后再使用
emulator
命令,如下例所示。示例 1:在下面的命令序列中,
adb devices
命令启动了 adb 服务器,但是设备列表未显示。停止 adb 服务器,然后按照所示顺序输入以下命令。对于 avd 名称,请提供系统中有效的 avd 名称。如需获取 avd 名称列表,请输入
emulator -list-avds
。emulator
命令位于android_sdk/tools
目录下。$ adb kill-server $ emulator -avd Nexus_6_API_25 -port 5555 $ adb devices List of devices attached * daemon not running. starting it now on port 5037 * * daemon started successfully *
示例 2:在下面的命令序列中,
adb devices
显示了设备列表,因为先启动了 adb 服务器。如果想在
adb devices
输出中看到模拟器,请停止 adb 服务器,然后在使用emulator
命令之后、使用adb devices
命令之前,重新启动该服务器,如下所示:$ adb kill-server $ emulator -avd Nexus_6_API_25 -port 5557 $ adb start-server $ adb devices List of devices attached emulator-5557 device
-
指定特定设备使用adb命令
如果有多个设备在运行,在发出 adb 命令时必须指定目标设备。为此,请使用 devices
命令获取目标设备的序列号。获得序列号后,请结合使用 -s
选项与 adb 命令来指定序列号
$ adb devices
List of devices attached
emulator-5554 device
emulator-5555 device
$ adb -s emulator-5555 install helloWorld.apk
安装应用
$ adb install out.apk
安装测试APK时,必须在install命令中使用-t选项。
$ adb install -t tesk.apk
设置端口转发
可以使用 forward
命令设置任意端口转发,将特定主机端口上的请求转发到设备上的其他端口。以下示例设置了主机端口 6100 到设备端口 7100 的转发:
$ adb forward tcp:6100 tcp:7100
以下示例设置了主机端口 6100 到 local:logd 的转发:
$ adb forward tcp:6100 local:logd
将文件复制到设备/从设备复制文件
可以使用 pull
和 push
命令将文件复制到设备或从设备复制文件。与 install
命令(仅将 APK 文件复制到特定位置)不同,使用 pull
和 push
命令可将任意目录和文件复制到设备中的任何位置。
如需从设备中复制某个文件或目录(及其子目录),请使用以下命令:
$ adb pull remote(手机目录) local(本地目录)
如需将某个文件或目录(及其子目录)复制到设备,请使用以下命令:
$ adb push local(本地目录) remote(手机目录 比如:/data/data/sdcard/xxx/xxx)
将 local
和 remote
替换为开发机器(本地)和设备(远程)上的目标文件/目录的路径。例如:
$ adb push foo.txt /sdcard/foo.txt
发出 adb 命令
可以从开发机器上的命令行发出 adb 命令,也可以通过脚本发出。用法如下:
adb [-d | -e | -s serial_number] command
如果只有一个模拟器在运行或者只连接了一个设备,系统会默认将 adb 命令发送至该设备。如果有多个模拟器正在运行,需要使用 -d
、-e
或 -s
选项指定应向其发送命令的目标设备。
您可以使用以下命令来查看所有支持的 adb 命令的详细列表:
adb --help
调用Activity管理器(am)
在 adb shell 中,可以使用 Activity 管理器 (am
) 工具发出命令以执行各种系统操作,如启动 Activity、强行停止进程、广播 intent、修改设备屏幕属性,等等。例如:
adb shell am start -a android.intent.action.VIEW
实例:
adb shell pm list permissions -d -g 查看手机危险权限
am start -n com.yc.sleepmm/com.yc.sleepmm.main.ui.activity.MainActivity 打开某个应用指定的页面
am start -a android.intent.action.VIEW -d http://www.google.cn/ 启动浏览器
am start -a android.intent.action.CALL -d tel:10086 拨打电话
adb -s 127.0.0.1:62001 shell dumpsys activity top => info.txt 获取栈顶的activity信息 并保存到info.txt文件中
adb -s 127.0.0.1:62001 logcat -s tag 获取APP的日志信息 tag是过滤的标签
adb -s 127.0.0.1:62001 logcat -s AndroidRuntime 获取运行时崩溃信息 对于程序突然崩溃获取信息非常有用
adb -s 127.0.0.1:62001 logcat -s AndroidRuntime > log.txt 将收集的崩溃信息保存到log.txt文件中
adb shell pm list permissions -d -g 列出所有的危险权限
adb logcat PictureFragment:D newHomeDebug:D *:S >log.txt
将APP中tag标记为"PictureFragment"且优先级大于等于"Debug" 和标记为"newHomeDebug"并且优先级大于等于"Debug"的日志输出到log.txt文件中
注:*:S用于设置所有标记的日志优先级为S,这样可以确保仅输出符合条件的日志。