Android 和 iOS App WebView 远程调试排查记录

需要调试 App WebView 时,先按平台选入口。Android 11 及以上能无线就优先无线,解决不了再插线兜底;iOS 有线 Web Inspector 目前最稳,Wi-Fi 路线官方支持,但这次没有复现出可检查内容。

Android 的无线调试是不插 USB,不是不用 ADB。它仍然要通过 Android SDK Platform-Tools 里的 adb pair / adb connect 建立连接。iOS 不走 ADB,入口在 Safari / WebKit / Xcode CoreDevice 这条链路。iOS 无线调试这次没有复现出可检查内容,日常排查先建议有线。

Android

先确认电脑能发现手机。Android 11 及以上建议先走无线调试;网络、系统版本或配对状态不稳定时,再回到 USB。设备连接成功后,还要确认 App WebView 是否暴露 DevTools target。

Chrome DevTools 的 Android 远程调试文档说明了 chrome://inspect/#devices 的基本路径。Android WebView 调试文档说明 App WebView 需要开启 debugging 后,才会出现在 Chrome DevTools 里。

需要无线配对、端口转发或检查 WebView socket 时,安装 Android SDK Platform-Tools 就够了,不需要完整 Android Studio。macOS 可以用 Homebrew 安装:

brew install android-platform-tools

安装后先确认 adb 可用:

adb version

无线优先

Android 11 及以上支持直接无线配对,不需要先插 USB。手机和电脑在同一个可靠网络里时,优先用这条路,少一根线,团队轮流使用同一台测试机也更方便。

开发者选项 -> Wireless debugging / 无线调试

打开开关后点进去,选择:

Pair device with pairing code / 使用配对码配对设备

手机会显示一个配对用的 IP:端口 和一组配对码。电脑上执行:

adb pair <PHONE_IP>:<PAIR_PORT>

输入手机显示的配对码后,回到无线调试主页面,那里会显示另一个连接用的 IP address & Port。再执行:

adb connect <PHONE_IP>:<DEBUG_PORT>
adb devices

这两个端口不是同一个:adb pair 用配对弹窗里的端口,adb connect 用无线调试主页面里的当前调试端口。后续已经配对过时,通常只需要重新 adb connect 当前调试端口;端口可能会变,仍然以手机页面显示为准。

Android 10 及以下通常要先插一次 USB,把 ADB 切到 TCP/IP 模式:

adb devices
adb tcpip 5555
adb connect <PHONE_IP>:5555
adb devices

这条路拔线后可以继续用,但手机重启或 ADB 状态变化后可能要重新来一次。

有线兜底

无线配对失败、公司 Wi-Fi 不稳定、系统版本较低或第一次确认链路时,再用 USB。基本流程是:

  1. 电脑安装 Chrome。
  2. 手机上打开开发者选项和 USB 调试。
  3. 用数据线连接手机和电脑,手机上确认允许 USB 调试。
  4. 电脑 Chrome 打开 chrome://inspect/#devices
  5. 打开 App 的 WebView 页面,在设备列表里找 WebView in <package>,点 inspect

有线连接后用 adb devices 看状态:

adb devices

理想状态是:

<device-id>    device

如果看到 unauthorized,先看手机上是否有「Allow USB debugging」弹窗。没有弹窗时,可以重启 ADB 服务再插一次线:

adb kill-server
adb start-server
adb devices

Windows 可能还要安装手机厂商 USB Driver。macOS 和 Linux 通常不用为有线 Chrome Inspect 单独安装完整 Android Studio。

WebView 需要由 App 暴露

ADB 连通只说明电脑能到手机,不说明 App WebView 一定可检查。App 侧需要开启 WebView debugging:

if (BuildConfig.DEBUG) {
    WebView.setWebContentsDebuggingEnabled(true)
}

Java 写法是:

if (BuildConfig.DEBUG) {
    WebView.setWebContentsDebuggingEnabled(true);
}

如果 chrome://inspect/#devices 能看到手机 Chrome 页面,却看不到 App WebView,可以先确认当前 App 进程有没有暴露 WebView 调试 socket:

adb shell cat /proc/net/unix | grep -E 'webview_devtools|devtools_remote'

没有 webview_devtools_remote_... 一类条目时,重点看 App 是否真的调用了 WebView.setWebContentsDebuggingEnabled(true),以及当前页面是否真的是 Android WebView,而不是 Chrome Custom Tabs、外部浏览器或其他容器。

如果手机 WebView 要访问电脑本地开发服务,优先用 adb reverse

adb reverse tcp:<LOCAL_PORT> tcp:<LOCAL_PORT>

例如本地 Vite 服务在 5173

adb reverse tcp:5173 tcp:5173

之后手机 WebView 访问:

http://127.0.0.1:5173

请求会被反向转发到电脑上的本地服务。

判断表

Android 侧可以按这个顺序判断:

现象 优先判断
adb devices 没有设备 有线看线、USB 调试、授权、驱动;无线看配对、同网段和当前调试端口
adb devicesdevice,Chrome Inspect 没有 WebView App WebView debugging 未开启,或当前页面不是 WebView
有 WebView target,但本地服务打不开 优先检查 adb reverse、手机网络和服务监听地址
Chrome Inspect 能打开,但当前扩展写不进去 远程 WebView 不是桌面 Chrome 当前 profile 的普通 tab,不能按普通扩展注入处理

iOS

iOS 不走 adb,也不走 chrome://inspect/#devices。iOS Chrome 本身仍然使用 WebKit,App 内 WebView 通常是 WKWebView,调试入口是 Mac 上的 Safari Web Inspector。

无线官方支持,但这次没有跑通

WebKit 的 Web Inspector 启用说明写到,iOS 设备启用 Web Inspector 后,通过物理线缆连接,或者在 Xcode 配置 wireless debugging 后,可以出现在 Safari 或 Safari Technology Preview 的 Develop 菜单里。Apple 的 Xcode 帮助文档也有 Pair a wireless device with XcodeRun an app on a wireless device,其中说明第一次需要用线连接、信任设备、启用 Connect via network,之后可以拔线,并通过 Bonjour 或 IP 地址发现网络设备。

这条路线和 Android 无线不同。Android 无线是 adb pair / adb connect;iOS 无线没有 ADB 命令,入口是 Safari 的 通过网络连接、Safari 的 检查 App 和设备 面板,以及 Xcode/CoreDevice 的设备连接状态。

这次按这个方向做过排查:

  1. iPhone 和 Mac 一开始不在同一个 Wi-Fi,切到同一个 Wi-Fi 后继续验证。
  2. iPhone 已开启 网页检查器 / Web Inspector
  3. iPhone 已开启 Developer Mode。
  4. Xcode Devices and Simulators 能识别 iPhone,并完成 Copying shared cache symbols
  5. Safari 开发 -> iPhone -> 通过网络连接 能点,但没有明显 UI 反馈。
  6. 当前 Xcode 右键设备菜单没有出现 Apple 文档里的 Connect via IP Address,只看到复制名称、复制标识符、重命名、显示 Provisioning Profiles、取消配对等项。
  7. 重配设备后表现不变。
  8. Safari Technology Preview 也表现一致。
  9. 换另一台 iOS 设备后表现一致。

命令层也做过确认。Xcode 路径正常:

xcode-select -p

输出:

/Applications/Xcode.app/Contents/Developer

插线时,devicectl 能看到设备为 connected

xcrun devicectl list devices

拔线后曾观察到 available (paired)。进一步看 verbose 输出时,关键信息是:

transportType: localNetwork
pairingState: paired
tunnelState: disconnected

这说明 Mac 已经通过局域网发现这台 iPhone,也记得配对关系,但当时真正用于调试的 tunnel 没建起来。

随后再按 Safari 的 通过网络连接 操作和等待后,拔线状态下 devicectl 可以显示 connected。新版 Safari 的 开发 菜单里不再出现 iPhone 子菜单,但 开发 -> 检查 App 和设备 面板里可以看到左侧有 iPhone,状态属于已连接设备。

卡住的地方是右侧始终显示:

无可检查内容

这个现象不受当前页面影响。iPhone 上打开系统 Safari 普通网页,右侧仍然没有内容;打开 App WebView,右侧也没有内容。插回数据线后,Safari 页面和 App WebView 又都可以 inspect。

这组现象把问题范围压得比较窄:

证据 说明
有线能 inspect iPhone Safari iPhone Web Inspector 和 Mac Safari 基础配置没问题
有线能 inspect App WebView App 的 WKWebView.isInspectable 或调试包状态没问题
拔线后 devicectl 能到 connected CoreDevice 设备连接层可以通过网络建立
检查 App 和设备 能看到 iPhone Safari 新面板能识别到网络设备
拔线后内容立刻变成空 无线状态下 inspectable targets 没有枚举出来
Safari Technology Preview 也一样 不像系统 Safari 单独 UI 问题
另一台 iOS 设备也一样 不像单台 iPhone 或单个 iOS 小版本问题

这些证据不能推出「iOS 不支持无线调试」。官方资料确实写了网络连接和 Xcode wireless debugging。但在当前组合里,无线只到了设备层,没有拿到可检查内容。最实用的判断是:本机环境下 iOS WebView 调试先走线缆。

有线调试

有线是这次实测稳定可用的方案。基本流程是:

  1. iPhone 打开 设置 -> Safari -> 高级 -> 网页检查器 / Web Inspector。新版系统可能在 设置 -> App -> Safari -> 高级
  2. Mac Safari 打开 设置 -> 高级,启用开发菜单或开发者功能。
  3. 用线连接 iPhone 和 Mac,手机上点信任这台电脑。
  4. 打开 iPhone Safari 页面,或打开 App 内 WebView 页面。
  5. Mac Safari 菜单栏进入 开发,选择 iPhone 下的页面或 App WebView。

App 内 WKWebView 还要允许 inspect。WebKit 在 Enabling the Inspection of Web Content in Apps 里说明,WKWebViewJSContext 可以通过 isInspectable 开启检查能力。iOS 16.4 及以上常见写法是:

if #available(iOS 16.4, *) {
    webView.isInspectable = true
}

这次现场有线调试已经确认可用:同一台 Mac、同一台 iPhone,在插线状态下可以 inspect iPhone Safari 页面,也可以 inspect App WebView。这说明 iPhone 的网页检查器、Mac Safari 开发菜单和 App WebView inspectability 都是通的。

iOS 无线的反推线索

后续如果把 iOS 无线调试跑通,可以优先按下面几条线反推。

第一条是区分设备连接和内容枚举。xcrun devicectl list devicesconnected 只能证明 CoreDevice 层可用,不能证明 Web Inspector 已经拿到 Safari 页面或 WKWebView target。后续记录里要同时写清:

xcrun devicectl list devices
xcrun devicectl list devices --verbose

以及 Safari 或 STP 的 检查 App 和设备 面板里是否出现具体页面。

第二条是看 tunnel 状态。available (paired) 更像「设备被记住且可发现」,不是实时连接。transportType: localNetworkpairingState: pairedtunnelState: disconnected 说明网络发现和配对都在,但调试隧道没起来。后续如果成功,应记录成功状态下 tunnelStatetransportType 和 Safari 面板内容的变化。

第三条是网络环境。Apple 的 Troubleshoot a wireless device 提到要确认同一网络、能 ping 到设备,并检查网络设备通信使用的 62078 端口。现场前三项曾经可用,但这只能证明基础可达,不等于 Bonjour、IPv6、CoreDevice tunnel 和 Web Inspector target 枚举都正常。后续最好用干净热点、家用路由器、公司 Wi-Fi 各测一次。

可以保留这两个命令作为最小网络检查:

ping -c 3 <IPHONE_IP>
nc -vz <IPHONE_IP> 62078

第四条是 macOS 本地网络权限。新版 macOS 对本地网络访问更敏感,Safari、Safari Technology Preview、Xcode 或相关系统服务如果没有 Local Network 权限,可能表现为发现或连接不完整。后续排查可以记录:

系统设置 -> 隐私与安全性 -> 本地网络

以及 Safari、STP、Xcode 是否在列表里并被允许。

第五条是交叉验证。现有证据已经覆盖两台 iOS 设备和两个 Safari 前端,但还缺另一台 Mac。如果另一台 Mac 在同一网络、同一 iPhone 上能列出无线内容,问题更可能在当前 Mac 的 CoreDevice、WebKit、权限或系统服务状态。如果另一台 Mac 也只能看到设备但没有内容,才更接近 Apple 当前版本组合的普遍问题或限制。

第六条是版本矩阵。现场至少记录过一台 iOS 18.5 设备和另一台 iOS 26.4 设备,Mac 侧显示 macOS 26.5。后续如果解决,需要把 Xcode、Safari、Safari Technology Preview、macOS、iOS、设备型号、网络环境一起写进记录。单独说「升级后好了」没有太大复用价值,必须知道是哪一层变了。

默认用法

Android App WebView 调试可以把无线作为优先路线,有线作为兜底路线:

  1. 无线:Android 11 及以上用 adb pair / adb connect,适合日常调试和多人轮流使用同一台测试机。
  2. 有线:Chrome + USB 调试 + chrome://inspect/#devices,适合首次确认、旧系统、网络不稳定或无线配对异常时兜底。
  3. 半无线:Android 10 及以下通常先 USB adb tcpip 5555,再 adb connect,拔线后继续调试。

Android 的关键前提是 App WebView debugging 是否开启。ADB 连接成功只是设备通,WebView.setWebContentsDebuggingEnabled(true) 才决定 App WebView 能不能出现在 DevTools target 列表里。这里的“无线”仍然是 ADB over Wi-Fi,不是脱离 ADB 的另一套 Chrome Inspect 机制。

iOS App WebView 调试目前按有线作为稳定方案:

  1. iPhone 开 网页检查器 / Web Inspector
  2. Mac Safari 或 STP 开开发菜单。
  3. App 内 WKWebView 按需设置 isInspectable = true
  4. 用数据线连接并从 Safari 的开发入口 inspect。

iOS 无线调试可以继续作为待验证能力记录,但不应该在团队流程里写成可靠默认方案。它和 ADB 无关,理论链路是 Safari / WebKit / Xcode CoreDevice。当前本机实测只证明:Apple 文档支持这条能力,设备连接层可以到 connected,Safari 新面板也能看到 iPhone;可检查内容在拔线后没有出现。日常排查如果赶时间,直接插线更稳。