Android远程调试Web页面

412 阅读3分钟

曾经有一段时间专门处理了一下远程调试的事情,要解决的问题是不依赖Chrome如何在移动设备中调试Web页面。有时候真的奇怪,因为我们老是自己制造问题,因为“墙”的存在被迫去解决这些本来不是问题的问题。

利用Chrome调试Android Web页面,本来是很好的事情,但是由于Google在打开调试面板时,这个域名是google.com,我们都知道这个域名在中国大陆被封了,但我们又要调试,于是陷入了黑暗的死循环。今天,要分享的就是,如何绕过google.com域名,并且能正常顺利的去调试Android Web页面。

利用Google官方提供的Android Debug Bridge工具,在本地启动一个本地Socket服务,来与设备进行交互。

阅读本文之前,请务必了解一下Android Debug Bridge工具,因为接下来我们会利用到它。

当我们运行adb start-server时,adb会在本地启动一个5037端口的本地服务,这个服务我们可以将其视为“远程”,然后需要在本地写一个客户端来连接这个服务。adb services分为两种,HOST SERVICES 和 LOCAL SERVICES,LOCAL SERVICES 需要等待一次HOST SERVICES 发送成功之后,之后发送的LOCAL SERVICES才能交互成功。在我们的调试工具中,主要利用到的是host:devices,host:transport: , :forward: ;  以及LOCAL SERVICES shell:command arg1 arg2…(官方文档: https://github.com/aosp-mirror/platform_system_core/blob/master/adb/SERVICES.TXT)。

在交互细节上Google定义了详细的协议(官方文档: https://github.com/aosp-mirror/platform_system_core/blob/master/adb/protocol.txt), 每一次的交互会返回4个长度的字节,而我们需要解析的就是这个如果是"OKAY",则说明交互成功。如果是“FAIL”则说明交互失败。

在进入调试面板后,会有一些准备工作要处理:

  • 使用host:transport:服务告诉设备,adb通过USB要连接设备的unix环境

  • 然后使用当前的socket连接继续发送shell命令 cat /proc/net/unix | grep --text _devtools_remote 获取到远程设备开启的socket地址

  • 最后使用 :forward: ; 服务进行一次映射

由于国内厂商的Android设备中的浏览器默认开启可调试,以及友商App的调试状态,我们还需要进一步的区分我们自己的环境。在我们去做forward映射时,就有可能获取到多个端口。这个时候,根据Devtools协议,可以通过http://localhost:<映射的端口>/json/version来获取远程调试环境的一些信息,格式如下:

{
  "Android-Package": "xxx",
  "User-Agent": "xxx",
  ….
}

将已获知的端口号循环请求一次,根据"Android-Package"来区分是否是自己的应用中。于是,我们可以得到正确的端口。再根据端口的映射http://localhost:<映射端口>/json来获取已打开的需要被调试的网页数组,如果你使用了UC内核1.0,那么在获取的devtoolsFrontendUrl中的commit_hash来匹配是否为188492,如果命中,直接唤起已经下载在项目中的DevTools工具。如果未命中,则依然load devtoolsFrontendUrl。

Chrome DevTools是一个开源项目,你可以通过:

  • https://docs.google.com/document/d/1WNF-KqRSzPLUUfZqQG5AFeU_Ll8TfWYcJasa_XGf7ro/edit#heading=h.xz439gqj1lwr 

  • https://github.com/ChromeDevTools/awesome-chrome-devtools

  • https://github.com/ChromeDevTools/devtools-frontend

整个文档将Protocol写的很清楚,了解完它不仅在此处有大作用,其实Node.js调试时也有很大的帮助。


长按二维码关注公众号:

你也可以关注我的新浪微博,搜索 i_icepy,很期待和大家交流