一、什么是adb?
ADB 是 Android Debug Bridge 的简称,是 Android 平台的调试工具。通过 adb 命令可以去获取安卓设备上的一些信息,也可以直接操作管理 Android 模拟器或者真实的 Android 设备。
ADB 采用客户端-服务端程序架构,简称 C-S 架构。主要包含以下三个组件:
1)客户端(adb client):运行在PC上,用来发送 adb 命令。
2)服务端(adb server):运行在PC上的一个守护进程,用来管理 adb client 端和 Android 设备上的 adbd 进程之间的通信。具体有以下两个作用:
- 检测 USB 端口感知设备的连接和拔除,以及模拟器实例的启动或停止。
- 将 adb client 的请求通过 usb 或者 tcp 的方式发送给 Android 设备上的 adbd 进程进行处理。
3)守护程序(adbd):运行在 Android 设备(真机/模拟器)后台的一个进程,它的主要作用是处理来自 adb server 的命令,然后获取对应 Android 设备的信息,最后将结果返回给 adb server。
二、adb的工作原理
当启动某个 adb client 时,该客户端会先检查是否有 adb server 进程正在运行。如果没有,它会先启动服务器进程,服务器进程在启动后会绑定到 5037 端口,并监听 adb client 发出的命令(所有 adb client 均通过 5037 端口与 adb server 进行通信)。如下图:
然后,服务器会与所有正在运行的设备建立连接,建立连接后,你便可以使用 adb 命令访问这些设备,由于服务器管理着设备的连接,并处理来自多个 adb client 的命令,因此你可以从任意客户端控制任意设备。
三、adb的通信流程
1)我们通过命令行界面或者 Android Studio工具等直接或间接的调用某个 adb 命令,比如 adb install 或者 adb devices。
2)这时候 adb client 进程会 fork 出一个子进程作为 adb server,而这个 fork 出的进程将常驻 PC 端,监听来自 adb client 端的请求。【fork()函数用于从一个已经存在的进程内创建一个新的进程,新的进程称为“子进程”,相应地称创建子进程的进程为“父进程”。使用fork()函数得到的子进程是父进程的复制品,子进程完全复制了父进程的资源,包括进程上下文、代码区、数据区、堆区、栈区、内存信息、打开文件的文件描述符、信号处理函数、进程优先级、进程组号、当前工作目录、根目录、资源限制和控制终端等信息,而子进程与父进程的区别有进程号、资源使用情况和计时器等。】
3)adb server 查找当前连接的真机或者模拟器,并接收来自 adb client 端发出的请求。
4)adb server 处理请求:如果是本地能直接处理的请求,就直接处理,比如:adb devices。如果是本地处理不了的请求,就会转发给连接的真机或者模拟器来进行处理,可以通过 usb 和 TCP/IP 的方式进行通信。
5)位于真机或者模拟器后台的 adbd 进程接收到请求后,通过 JDWP 协议转发给对应的 Java 虚拟机进程处理。
6)adbd 将处理后的结果返回给 adb server。
7)adb server 再将结果返回给 adb client,这时候我们就在命令行界面中看到结果了。
四、常见的adb命令
1)连接Android手机或模拟器
在输入其他的adb命令之前,应该先使用adb连接到Android手机或模拟器。
注:连接之前,需要打开Android手机或模拟器的开发者模式和USB调试。
一、华为手机开启adb的调试模式方法
a)点开设置 -> 关于手机,连续按几次 “HarmonyOS版本”。
b)退到上一层,点开系统和更新 -> 开发人员选项。
c)选中 “仅充电模式下允许ADB调试” 和 “USB调试”(打开的先后顺序不能变)。
二、模拟器开启adb的调试模式方法
a)点开设置 -> 关于平板电脑,连续按几次 “版本号”。
b)退到上一层,点开开发者选项。
c)选中 “USB调试”。
# 列出当前已连接的所有设备
adb devices
我将模拟器开启了adb的调试模式,但是通过上述命令未看到模拟器的连接。我使用的是MuMu模拟器,该模拟器的端口是7555,因此可以通过下列命令连接到模拟器。
# 连接设备
adb connect IP地址:端口
2)停止和启动adb server
一般情况下不需要专门启动adb server,它会自动启动,只需要连接就好了。如果确实是由于adb有问题而导致操作出现错误,就需要重启adb server。并且每次重启adb server后,都需要重新连接设备。
# 停止adb server
adb kill-server
# 启动adb server
adb start-server
可以编写下面这样的一个批处理文件connect_device.bat,直接双击运行,就会自动执行下列命令。如果以后在操作时,突然adb server挂了,那么就可以运行该文件恢复连接,非常方便。
pause命令是让当前命令窗口保持在当前页面,不会消失,等待进行下一步操作。如果没有这条命令,上面的命令执行完之后,当前命令窗口就会自动关闭消失。而当前窗口保持在当前页面后,就可以查看上面命令是否执行成功、是否连接到设备。
adb kill-server
adb start-server
adb connect 127.0.0.1:7555
pause
3)查看端口占用进程
adb server进程在启动后会绑定到 5037 端口,如果发现adb server无法启动,可以通过下列命令来查询是否有其他进程占用了该端口。
# 查询占用5073端口的进程
netstat -ano | findstr 5037
TCP 127.0.0.1:5037 0.0.0.0:0 LISTENING 11072
# 杀掉对应的进程,释放端口
taskkill -f -pid 11072
4)进入设备的shell模式
由于Android底层是基于Linux的,所以常用的一些Linux命令都是可以运行在Android系统中。
# 进入模拟器的shell模式,进入shell后,可以执行Linux命令
adb shell
5)获取已安装应用的包名和Activity名
包名:package name,是Android系统中标识一个app应用的唯一标识,不同的app应用可以有相同的名字,但是它们的包名是不同的。比如:我可以自己编译生成一个app应用,也叫做 “微信”,但是我的app应用的包名不能是com.tencent.mm(微信的包名),如果我的app应用的包名也设置成com.tencent.mm,那么一台手机上只允许安装这两个app应用中的其中一个。
Activity名:指的是app应用中我们看到的页面,一个页面就是一个Activity,获取Activity名其实就是获取页面名。
应用场景:自动化测试需要通过代码的形式告诉手机测试的是哪个应用的哪个界面,所以需要知道应用的包名和页面的Activity名。
# 获取设备当前显示页面的Activity名
adb shell dumpsys window windows | findstr mFocusedApp
6)文件传输命令
在将文件从设备上导入到电脑时,应当注意,由于权限问题不能将文件导入到电脑根目录(比如导入到D盘根目录,会报错),只能导入到某个具体文件夹内(文件夹需要事先存在,否则会报错)。
# 将文件从电脑上发送到设备中
adb push 电脑上的文件路径名 设备上的文件夹路径
# 将文件从设备上导入到电脑中
adb pull 设备上的文件路径名 电脑上的文件夹路径
示例1:先在电脑 E:\Test\ 路径下创建 demo.txt 文件,然后在该路径下打开 cmd 命令窗口,将 demo.txt 文件发送到模拟器中的 /sdcard/ 目录下。
示例2:将模拟器中的 /sdcard/ 目录下的 demo.txt 文件导入到电脑D盘根目录下。
示例3:将模拟器中的 /sdcard/ 目录下的 demo.txt 文件导入到电脑 D:\ADBTest\ 路径下。
7)安装和卸载app应用
# 往默认连接的手机设备上安装app应用
# 注:apk安装包的文件名不能含有中文或特殊字符,否则安装会报错
adb install apk包路径
# 覆盖安装app应用
# 比如有新版本了,再次安装时需要携带-r参数,否则会提示app应用已经安装过了。
adb install -r apk包路径
# 往指定连接设备中安装app应用
# 当连接了多个设备时,可以通过-s参数指定向哪台设备上安装app应用
adb -s 127.0.0.1:7555 install apk包路径
# 卸载app应用
adb uninstall app应用的包名
8)查询本机安装的所有应用程序包
# 查询本机安装的所有应用程序包
adb shell pm list packages
# 查询本机安装的所有第三方应用程序包
adb shell pm list packages -3
9)根据apk文件查询包名和启动Activity的名称
- 有apk安装包的情况下,使用aapt工具进行查看,查看命令如下:
aapt dump badging apk文件路径 | findstr package
aapt dump badging apk文件路径 | findstr launch
- 没有apk安装包的情况下(比如从手机应用商店下载的软件,会直接安装到手机,没有apk安装包),将app应用运行起来,然后使用abd命令进行查看:
adb shell dumpsys activity activities | findstr Run
10)获取当前页面的截图
注:截图保存的路径只能是手机里面的路径。
adb shell screencap 截图保存的路径
示例:这里先获取当前app应用页面的截图,将其保存在 /sdcard/ 路径下,然后将该截图从手机上导入到电脑中。