adb devices 卡住几秒甚至几分钟?元凶竟是苹果的 Bonjour

adb devices 卡住几秒甚至几分钟?元凶竟是苹果的 Bonjour

背景

最近调试 Android 应用时发现 adb devices 经常卡住很久,有时几秒,有时长达几分钟。起初以为是 Wi-Fi ADB 无线连接网络不稳定导致的,换成 USB 线后问题依旧;后来在没有连接任何设备的情况下,单独执行 adb devices 也会卡很久,说明问题出在 ADB Server 启动阶段。

最终定位到元凶:Windows 上安装的 Apple Bonjour 服务。

排查过程

1. 确认基本环境

先确认 adb 版本、路径和进程状态:

adb version
Get-CimInstance Win32_Process -Filter "Name='adb.exe'" | Select-Object ProcessId, ExecutablePath
netstat -ano | findstr 5037

结果:只有一个 adb 进程,也是最标准的 5037 端口监听者,没有多版本 adb 冲突(这类冲突常见于安装了夜神、雷电等模拟器时,各自的 adb 会抢占 5037)。

也没有设置过任何 ADB_* 环境变量。

2. 实测启动耗时

杀掉 server 后重新计时:

adb kill-server
Measure-Command { adb devices }

发现 server 已在运行时响应几乎为 0,卡顿只发生在 server 冷启动 阶段。但单独重启的话耗时大约 2 秒,算不上”卡很久”——这是典型的间歇性问题。

3. 检查 5353 (mDNS) 端口

新版 adb(31.0.0+)在 server 启动时会通过 mDNS 做设备发现(配合 Android 11+ 的无线调试配对),需要绑定 UDP 5353 端口。检查该端口占用:

netstat -ano -p udp | findstr 5353

发现了adb 之外的进程:PID 4968,经查询为 mDNSResponder,文件路径:

C:\Program Files\Bonjour\mDNSResponder.exe

即 Apple 的 Bonjour 服务。此外还有 Windows 自身的 Dnscache (svchost) 也监听了 5353。

4. 验证猜想

卸载 Bonjour(winget uninstall --id Apple.Bonjour)后重启 adb server,mDNS 保持默认开启,启动耗时稳定在 2 秒左右。之后一段时间内 adb devices 再未出现过卡住的情况——确认是 Bonjour 导致。

根因分析

  • ADB Server 启动时会初始化 mDNS 后端,包括绑定 UDP 5353,并参与组播查询。
  • Windows 上 UDP 5353 是 mDNS 标准端口,允许多进程同时绑定(SO_REUSEADDR)。但当一个常驻的 mDNSResponder(Bonjour)已经在跑时,adb 的 mDNS 模块在某些网络环境(多网卡、虚拟网卡、防火墙拦截组播包等)下会出现阻塞等待,表现为 server 启动卡住,进而让所有 adb 客户端命令长时间无响应。
  • 由于是间歇性的(与防火墙策略、网络状态有关),时快时慢,非常具有迷惑性。

解决方案

  1. 卸载 Bonjour(本次的实测有效解):
    winget uninstall --id Apple.Bonjour
    

    该服务通常随 iTunes 或某些 Apple 软件、Bonjour SDK 被装进系统;如果没有刻意使用 iTunes 相关功能,一般可以放心卸载。

  2. 备选方案:不禁用系统上的 mDNS,只禁掉 adb 自己的 mDNS 模块(不影响 USB 调试和手动 adb connect,但会失去无线自动发现设备的能力):

    # 用户级环境变量
    setx ADB_MDNS 0
    
  3. 卸载/改完后记得重启 adb server:
    adb kill-server && adb devices
    

总结

  • adb devices 卡顿且与是否连接设备无关时,先怀疑 server 启动阶段 的问题,而不是客户端/网络。
  • Windows 上 mDNS 相关的端口占用(5353)、多版本 adb 抢占 5037、杀软拦截,是这类卡顿最常见的三个来源。
  • 排查工具:netstat -ano -p udp | findstr 5353、Get-CimInstance Win32_Process(PowerShell)、Measure-Command { adb devices }。
  • 有时问题的表象(USB/Wi-Fi 断连)和根因(一个后台服务的端口冲突)之间隔着好几层,靠”逐步缩小变量范围”(先排除设备 → 再定位到 cold start → 再找到端口占用)才是解这类问题的正道。

环境:Windows 11 / platform-tools 36.0.0 / Bonjour 3.1.0.1

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

 桂ICP备15001694号-3