曾经有一段时间专门处理了一下远程调试的事情,要解决的问题是不依赖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”则说明交互失败。
在进入调试面板后,会有一些准备工作要处理:
由于国内厂商的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是一个开源项目,你可以通过:
整个文档将Protocol写的很清楚,了解完它不仅在此处有大作用,其实Node.js调试时也有很大的帮助。