chrome dev远程调试android 和ios

调试是开发过程很重要的过程,而随着移动端的普及,移动开发也越来越多,并且由于移动端的诸多限制,使得调试相对PC复杂很多。因此远程调试就显得非常重要了。 近几年,浏览器厂商也纷纷推出自己的远程调试工具,比如Opera Mobile 推出的Opera Dragonfly,iOS Safari 可以开启Web检查器在 Mac OS X系统中实现远程调试。Android 4.0+系统的 Chrome for Android可以配合 ADB(Android Debug Bridge)实现桌面远程调试,桌面版Chrome 32+已经支持免安装ADB即可实现远程调试移动设备页面/WebView 。国内的UC浏览器开发者版也推出了自己的远程调试工具RemoteInspector。除了浏览器厂商之外,也涌现出许多第三方开发的远程调试工具,诸如支持全平台调试的Weinre等。

TL,NR,先介绍一下anydebugger方案吧,原理复杂使用简单,参考:支持任意端的基于Chrome devTools远程调试技术方案

远程调试

那么远程调试就是调试运行在远程的APP。比如手机上访问google,我需要在PC上调试手机上运行的google APP。 这个就叫做远程调试。

远程调试大概有三种类型:

  • 调试远程PC(本质上是一个debug server 和 一个debug target,其实下面两种也是这种模型,ios中间会多一个协议转化而已) 这种类型下的debug target就是pc, debug server 也是pc。
  • 调试android webpage/webview(很多方式,但安卓4.4以后本质都是Chrome DevTools Protocol的扩展) 这种类型下的debug target就是android webview,debug server 是pc。
  • 调试ios webpag/webview(可以使用iOS WebKit Debug Proxy代理,然后问题便退化成上述两种场景) 这种类型下的debug target就是ios webview, debug server 是pc。

上图展示了基于adb的chrome webview 的 debug的架构。

Android webview 调试

unix domain socket是linux下面的用于进程间通讯IPC的一种socket,(参考:https://blog.csdn.net/guxch/article/details/7041052)

android4.4 版本之后,可以配置开启 WebViews 调试,支持直接使用chrome dev tool调试Android webview。(参考: https://developers.google.com/web/tools/chrome-devtools/remote-debugging/webviews?hl=zh-cn)

必须从您的应用中启用 WebView 调试。要启用 WebView 调试,请在 WebView 类上调用静态方法 setWebContentsDebuggingEnabled

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    WebView.setWebContentsDebuggingEnabled(true);
}

此设置适用于应用的所有 WebView。

提示:WebView 调试不会受应用清单中 debuggable 标志的状态的影响。如果您希望仅在 debuggable 为 true 时启用 WebView 调试,请在运行时测试标志。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    if (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE))
    { WebView.setWebContentsDebuggingEnabled(true); }
}

Android的webview debugger socket是一种unix domain socket,所以我们要基于adb来和这个socket通信。

adb通信原理

电脑上通过adb命令和手机上的adb守护进程通信,其中采用的通信方式是 smart socket。

android提供了smartsocket,详见这里

> — smartsockets ——————————————————-  
> Port 5037 is used for smart sockets which allow a client on the host  
> side to request access to a service in the host adb daemon or in the  
> remote (device) daemon. The service is requested by ascii name,  
> preceeded by a 4 digit hex length. Upon successful connection an  
> “OKAY” response is sent, otherwise a “FAIL” message is returned. Once  
> connected the client is talking to that (remote or local) service.  
> client:  
> server: “OKAY”  
> client:  
> server: “FAIL”

总结来说,就是可以给adb-server发送一条指令<service-name>,然后adb-server会转发给adbd,让adbd来执行<service-name>.
举例来说,当我们执行adb shell cat /proc/net/unix,最终就是通过adbd在设备上执行的。

Stetho的通信模型如上图,其中stetho-server就是app启的一个Thread用来accept客户端的connect。

链接unix domain socket

手机通过usb链接电脑(adb over wifi参考后面),并开启调试模式,运行下列命令,如果查到abstract socket:@chrome_devtools_remote,则表明chrome for android 开启了unix domain socket。如果查到abstract socket@webview_devtools_remote_27594,则说明了AndroidWebView也开启了unix domain socket。

$ adb shell cat /proc/net/unix | grep --text  _devtools_remote
00000000: 00000002 00000000 00010000 0001 01 3517288 @webview_devtools_remote_27594
00000000: 00000002 00000000 00010000 0001 01 3535173 @chrome_devtools_remote
00000000: 00000003 00000000 00000000 0001 03 3546131 @chrome_devtools_remote

直接过滤 webview

$ adb shell grep -a webview_devtools_remote /proc/net/unix
0000000000000000: 00000002 00000000 00010000 0001 01 14832 @webview_devtools_remote_2621
0000000000000000: 00000002 00000000 00010000 0001 01 459297 @webview_devtools_remote_m5x_17803
0000000000000000: 00000003 00000000 00000000 0001 03 455603 @webview_devtools_remote_2621

后面带的_2621 这种是对应的pid,采用下面的命令可以建立本地9223端口转发到远程手机的unix domain socket(webview_devtools_remote_m5x_17803),这样就可以在本地访问到这个android webview debug server (关于adb forward, 参考:https://www.cnblogs.com/fwindpeak/archive/2013/05/20/3088895.html)

adb forward tcp:9223 localabstract:webview_devtools_remote_m5x_17803

浏览器访问下这个9223端口,因为http协议底层走的也是tcp所以可以直接用浏览器看下:https://localhost:9223/json

[ {
"description": "    {\"attached\":true,\"empty\":false,\"height\":1232,\"screenX\":0,\"screenY\":48,\"visible\":true,\"width\":720}",
"devtoolsFrontendUrl": "https://chrome-devtools-frontend.appspot.com/serve_rev/@a000f5daeaac3f79102a0c8f6eaab57aa0e00ae9/inspector.html?ws=localhost:9223/devtools/page/e5158e4a-d1df-4c43-b56c-fd19319dcadb",
"id": "e5158e4a-d1df-4c43-b56c-fd19319dcadb",
"title": "天猫超市",
"type": "page",
"url": "https://chaoshi.m.tmall.com/?disableNav=YES&utparam=%7B%22ranger_buckets%22%3A%22null%7C2895%22%2C%22ranger_buckets_native%22%3A%223801_4402_3151%22%7D&spm=a2141.1.icons.5&scm=2019.1.2.1007&_ig=shoutao&disableAB=1",
"webSocketDebuggerUrl": "ws://localhost:9223/devtools/page/e5158e4a-d1df-4c43-b56c-fd19319dcadb"} ]

返回一个数组,里面是所有可以远程调试的页面,其中包含以下字段信息:
- description: 页面信息描述
- devtoolsFrontendUrl:调试url地址,这个基于chrome 云服务器提供的inspector来调试,你也可以用开源的chromium中的inspector或者自己网上找下有人提取出来的调试server。
- id:页面id
- webSocketDebuggerUrl:android webview debug server 的 websocket, 这个地址的host和端口号是根据当前的访问tcp链接动态生成的,因为unix domain socket是没有ip地址和端口的。

调试方法

基于chrome浏览器调试

其实链接手机到浏览器后,只要开启了调试模式,开启了调试webview,打开浏览器的下面url页面,勾选发现Discover USB devices和Discover network devices,会自动发现可调式的设备,列出可调式网页页面。

chrome://inspect/#devices

点击列表前面的inspect,chrome会自动弹出调试窗口调试。

基于inspector.html网页调试

chrome浏览器的调试原理其实和这个基于网页的调试是一样的。这里为了更清晰的说明原理。上面基于adb forward实现端口映射之后,也可以拿到webview的debug web socket。那么就可以基于这个web socket调试了。其实打开上面那个devtoolsFrontendUrl

就可以了,链接已经拼接好了。

https://chrome-devtools-frontend.appspot.com/serve_rev/@a000f5daeaac3f79102a0c8f6eaab57aa0e00ae9/inspector.html?ws=localhost:9223/devtools/page/e5158e4a-d1df-4c43-b56c-fd19319dcadb",
“id”: “e5158e4a-d1df-4c43-b56c-fd19319dcadb

其中:

  • https://chrome-devtools-frontend.appspot.com/serve_rev/@a000f5daeaac3f79102a0c8f6eaab57aa0e00ae9/inspector.html是chrome云服务器托管的实现了 chrome devtools protocol (https://chromedevtools.github.io/devtools-protocol/)的调试器。chrome浏览器中已经默认集成了。
  • 后面的参数ws=localhost:9223/devtools/page/e5158e4a-d1df-4c43-b56c-fd19319dcadb",<br /> "id": "e5158e4a-d1df-4c43-b56c-fd19319dcadb 就是webview的debug web socket,同时遵循chrome devtools protocol ,基于 JSON RPC格式和调试器互相通信

wifi调试

目前主要的调试方式是safari和chrome远程调试模拟器和真机。ios下safari的调试工具其实并不太友好,可以统一采用chrome调试工具远程调试。
    remotedebug-ios-webkit-adapter (https://github.com/RemoteDebug/remotedebug-ios-webkit-adapter) 这个项目可以实现将ios的远程调试协议转为chrome远程调试协议,实现在chrome上调试真机和模拟器。
    wifi调试,
iphone支持connect via network的,但是貌似需要在同一子网,但是公司内网分配ip基本不在同一子网。
android可以采用adb over wifi 来实现,但是手机需要root才能在手机上开启(可以用下面的apk)。或者需要android手机先连上电脑,通过adb命令开启adb over tcp,然后adb连接到手机 ip:port 就可以实现无数据线调试。
ID=$(adb devices | awk -F'device' '{if (match($0, /device$/)) print $1}')
adb shell netcfg
IP=$(adb shell ifconfig wlan0 | awk '{if (sub(/.*ip/,"")) print $1 }')
adb tcpip 5555
adb connect $IP:5555

参考:

  1. 揭秘浏览器远程调试技术:https://taobaofed.org/blog/2016/10/19/chrome-remote-debugging-technics/
  2. weex debugger: https://github.com/weexteam/weex-debugger
  3. Chrome for Android Remote Inspector 原理:https://blog.csdn.net/xxhforest/article/details/52204197
  4. 前端调试:https://juejin.im/post/5a921819f265da4e832684d1
  5. chrome devtools protocol viewer: https://chromedevtools.github.io/devtools-protocol/
  6. https://github.com/cyrus-and/chrome-remote-interface/blob/master/README.md
  7. Puppeteer:https://juejin.im/entry/5a3aa0e86fb9a045076fd385
  8. https://segmentfault.com/a/1190000004322742
  9. 远程调试协议:https://testerhome.com/topics/2047
  10. https://github.com/ChromeDevTools/awesome-chrome-devtools


请遵守《互联网环境法规》文明发言,欢迎讨论问题
扫码反馈

扫一扫,反馈当前页面

咨询反馈
扫码关注
返回顶部