ADB与 Android 设备建立连接并进行通信

1 通过 USB 连接的设备使用adb

在设备系统设置中启用 USB debugging(位于 Developer options 下)。

在运行 Android 4.2 及更高版本的设备上,Developer options 屏幕默认情况下处于隐藏状态。如需将其显示出来,请转到 Settings > About phone 并点按 Build number 七次。返回上一屏幕,在底部可以找到 Developer options。

在某些设备上,Developer options 屏幕所在的位置或命名方式可能有所不同。

现在,您可以将设备与 USB 连接。可以从 android_sdk/platform-tools/ 目录执行 adb devices 来验证设备是否连接。如果已连接,您将看到设备名称以"设备"形式列示。

连接运行 Android 4.2.2 或更高版本的设备时,系统将显示一个对话框,询问您是否接受允许在这台计算机上调试的 RSA 密钥。这种安全机制可以保护用户设备,因为它可以确保只有在您能够解锁设备并确认对话框的情况下才能执行 USB 调试和其他 ADB 命令。

2 ADB与 Android 设备建立连接并进行通信

这个过程包括多个步骤,下面将从底层原理详细解释每个步骤:

1. ADB 服务器的启动和端口绑定

  • 服务器检查 :当通过命令行界面运行任何 adb 命令时,例如 adb devices,ADB 客户端首先会检查是否已经有一个 ADB 服务器进程在运行。如果没有,它会启动一个新的服务器进程。
  • 端口 5037:ADB 服务器启动后,会在主机上绑定 TCP 端口 5037。这个端口用于监听来自所有 ADB 客户端的命令。

2. 客户端与服务器的通信

  • 命令传递:客户端通过 TCP 端口 5037 向服务器发送命令。这些命令可以是列出连接的设备、安装应用、传输文件等。
  • 服务器响应:服务器接收这些命令并对其进行处理,包括发送命令到具体的设备或模拟器。

3. 设备发现和连接

  • 端口扫描:ADB 服务器会扫描 TCP 端口范围从 5555 到 5585 的奇数端口来查找已连接的模拟器或设备实例。每个 Android 设备或模拟器在主机的网络上通过一个特定的奇数端口与 ADB 服务器进行通信。
  • 发现设备:一旦 ADB 服务器通过奇数端口发现一个设备的 ADB 守护进程,它就会与该端口建立一个连接。

4. 设备端口的组织

  • 端口配对:每个模拟器或设备实例通常会获得两个连续的端口号:一个偶数端口用于模拟器的控制台连接(允许对模拟器本身进行控制),一个奇数端口用于 ADB 通信(允许进行应用安装、日志获取、文件传输等操作)。
  • 端口通信:通过这种方式,ADB 服务器可以通过特定的端口与设备的 ADB 守护进程通信,同时还可以通过相邻的偶数端口访问模拟器的控制台。

5. ADB 通信细节

  • 命令执行:通过建立的连接,ADB 服务器可以向设备发送具体的命令,设备的 ADB 守护进程则执行这些命令,并将结果返回给服务器,服务器再将结果反馈给原始请求的客户端。
  • 数据传输:此外,这个连接还用于文件的传输,例如安装 APK 文件或从设备拉取数据等。

这一系列操作确保了 ADB 可以高效地管理与 Android 设备的通信,无论是物理设备还是模拟器。ADB 的这种设计使其成为一个强大的工具,用于开发、测试和管理 Android 设备。

安全性和验证

安全验证:为了保证安全性,当设备第一次尝试通过 ADB 连接到开发机时,用户需要在设备上确认一个授权对话框。这确保了只有被授权的计算机可以通过 ADB 控制设备。

加密密钥:此外,从 Android 4.2.2 开始,ADB 连接过程中使用 RSA 密钥对进行身份验证,增强了连接的安全性。

这一交互机制确保了 ADB 工具在设备管理和应用开发过程中的高效与安全,是 Android 平台开发和测试的重要组成部分。

ADB 的组成主要是由三部分构成:

① adb client

1、功能:通过 socket 连接到 adb server, 指令的输入输出

2、启动 adb server:如果服务没有启动则启动服务

3、与 adb server 的通讯:连接对应的服务,发送请求,请求对应服务,返回应答的字符串

②adb server

1、功能:既是 adb client 的服务端,又是 adbd(device 端)的客户端

2、命令处理:处理 client 部分命令 (host:xxx)本地命令,如果本地处理不了的命令,将转发client 命令到 adbd,由 adbd 进行处理

3、与 adbd 通讯协议: A_OPEN 开始服务、A_OKAY 远程应答、A_WRTE 写数据、A_CLSE 关闭服务

4、实现方式:开启 tcp 监听服务,等待 adb_client 连接,启动 fdevent 循环,扫描并连接device

③Adbd (device端的daemon)

逻辑就基本上跟 adb server 一样,会获取属性服务器的值进行一些设置,权限控制,是否开启 tcp transport 等。

ADB源码分析https://www.zhihu.com/market/pub/119583838/manuscript/1057410063110635520

3 ADB服务器时遇到错误

使用 Android Studio 或直接通过命令行接口尝试启动 ADB 服务器时遇到错误信息:"'C:\Users\88\AppData\Local\Android\Sdk\platform-tools\adb.exe start-server' failed -- run manually if necessary",这表明尝试自动启动 ADB 服务器失败了。这可能由几个原因引起,以下是一些解决此问题的建议步骤:

1. 手动启动 ADB 服务器

打开命令提示符或终端,并尝试手动启动 ADB 服务器。这可以帮助确认问题是否出在自动启动过程上。

bash 复制代码
C:\Users\88\AppData\Local\Android\Sdk\platform-tools\adb.exe start-server

2. 检查 ADB 进程

有时候,如果已经有一个 ADB 服务器进程在运行,尝试再次启动可能会失败。你可以检查并结束任何现存的 ADB 进程,然后再次尝试启动。

Windows:

在命令提示符中运行:

bash 复制代码
tasklist | find "adb"

如果找到了 ADB 进程,可以结束它:

bash 复制代码
taskkill /IM adb.exe /F

然后,重新尝试启动 ADB 服务器。

adb start-server一般会把这个命令和kill-server一起用,即kill-server之后,重新start-server,这里启动的是:adb的服务器端。

如果想要start-server,只要执行任何一条非kill-server的adb命令就可以,比如:adb devices就可以。执行adb命令的时候,会首先判断服务器是否已经启动,如果没有启动,则会启动adb服务器。

服务器端的端口可能有时会出现被占用的情况,比如360手机助手、91助手等,一连接手机之后,就把5037的端口号占用了,这种情况下要如何处理?

此种情况下需要通过判断当前有哪些进程占用了5037的端口,然后把这些进程杀死,之后再start-server,之后执行adb devices查看设备是否能够正常展示出来。有时连接设备很久执行adb devices也不出现设备列表,此时可能会通过插拔设备,也可以通过kill-server之后重启服务来尝试。

相关推荐
太空漫步112 小时前
android社畜模拟器
android
海绵宝宝_5 小时前
【HarmonyOS NEXT】获取正式应用签名证书的签名信息
android·前端·华为·harmonyos·鸿蒙·鸿蒙应用开发
凯文的内存6 小时前
android 定制mtp连接外设的设备名称
android·media·mtp·mtpserver
天若子7 小时前
Android今日头条的屏幕适配方案
android
林的快手8 小时前
伪类选择器
android·前端·css·chrome·ajax·html·json
望佑8 小时前
Tmp detached view should be removed from RecyclerView before it can be recycled
android
xvch11 小时前
Kotlin 2.1.0 入门教程(二十四)泛型、泛型约束、绝对非空类型、下划线运算符
android·kotlin
人民的石头14 小时前
Android系统开发 给system/app传包报错
android
yujunlong391915 小时前
android,flutter 混合开发,通信,传参
android·flutter·混合开发·enginegroup
rkmhr_sef15 小时前
万字详解 MySQL MGR 高可用集群搭建
android·mysql·adb