几乎每个云测平台或手机厂商都有云真机业务,解决了小团队真机设备覆盖不足、资产管理困难的问题,让开发者可以像本地设备一样在线操控和调试设备。云真机平台一般附带一些辅助操作平台,可以通过拖拽的方式安装APP,同步黏贴板,查看log,截屏跑自动化,等等这些都可以在浏览器内完成,确实给研发测试都带来了不少便捷。
云真机通过一个设备管理系统,将这些真机对外租用,相比于传统的实体机租用,在线租用免去了实体机快递和硬件损坏风险的问题,随租随用,资费透明。
但他们都有一个共同点,贵,超级贵,按秒计费。
主流的云真机平台有腾讯WeTest远程调试、TestIn远程真机、百度测试云真机等,下面是百度云真机官网的介绍。
ADB是什么
在讲云真机之前,需要先说说什么是ADB。
全名:Android Debug Bridge
官方解释:
Android 调试桥 (adb) 是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。
ADB可分为三个部分:
- 客户端
该组件发送命令。客户端在开发计算机上运行。您可以通过发出 adb 命令从命令行终端调用客户端。 - 后台程序
该组件在设备上运行命令。后台程序在每个模拟器或设备实例上作为后台进程运行。 - 服务器
该组件管理客户端和后台程序之间的通信。服务器在开发计算机上作为后台进程运行。
打开开发者调试模式发生了什么
ADB的后台程序相当于一个跑在手机上的服务器,通过约定的协议以TCP的方式和PC的客户端交互,执行命令。比如 adb install命令,实际上是往手机上传了一个apk文件,然后告诉手机的安装程序安装这个apk;比如断点调试代码,实际上是IDE和手机之间通过adb互传代码执行信息,代码行号之类的。
研发可以通过开启一个SocketServer来欺骗adb,执行adb connect命令就会显示连接了一个设备,可以看到每条adb命令发出的是什么样的报文,当然孤独的adb是得不到任何回应的,它连的是假的设备。
adb的权限极大,可以在偷偷的执行命令而用户看不到,就像电脑上安装了360杀毒软件,连上手机后,手机上会默默的多出一个360安全助手APP。。。
这个后台程序默认是不开启的,当你打开和关闭手机开发者设置里面的调试模式后,其实就是在开关这个后台程序。
所以不建议普通用户的手机打开这个功能,哪怕360给你说出一万个打开调试模式的好处,也不要开。
云真机是什么
这些云测平台没有骗你,真的在云端跑了大量的真机,不是虚拟机不是模拟器。所以贵也是有道理的,当你租用这个手机的时候,就是独占了一台价值不菲的设备,消耗着不小的带宽。
云真机原理
云真机本质上就是远程控制手机,并且通过API的方式间接调用adb命令和手机交互。
云测平台的服务器通过一些高端的USB HUB连接了很多真机,再通过一个设备管理系统,将手机屏幕类似直播的方式显示到用户的浏览器上,再接收浏览器的上的手势操作回传给服务器。
云真机原理
上面提到这些云测平台的云真机服务,基本都是在一个叫STF的开源软件基础上定制开发而来的。
STF 全名Smartphone Test Farm,是一个安卓设备管理在线平台(也在扩展ios支持),刚开始被设计用来将将公司内部众多的安卓设备资产统一管理,并可以直接在个人电脑上在线使用手机,后来这些云测平台改改UI,变成了一个对外租用服务。
STF平台架构
STF架构的官方说明可以看看GitHub上的DEPLOYMENT.md
这个有点不好理解,这里画个简版的架构图:
这里面几个关键角色介绍一下:
- 手机:
普通的安卓设备,上面会运行着一个叫Minicap的APP(在首次接入系统时被自动安装),在被租用时会以每秒60张的速度高速截图,并通过这个系统发送给用户,同步画面。 - 设备提供方:
就是直接连着手机的电脑,负责发送设备连接状态、转发画面以及执行adb命令等任务。 - 消息服务:
通过消息队列(ZeroMQ),向整个系统的各个模块广播设备在线状态、租用状态等信息,充当中间人。 - Web服务:
一个NodeJs写的后台服务器,提供在线管理平台和API服务。 - 认证服务:
提供用户认证的服务,默认没有认证,内置一个仅需提供邮箱并且不校验的简单认证服务。一般需要定制扩展,集成内部的CAS、LDAP等认证系统。 - 数据库:
保存设备的信息,如设备型号、分辨率、在线状态、租赁状态、备注等等。STF默认用的是一个叫RethinkDB的冷门数据库,不好部署,大部分定制系统都会将其替换成MySql等。 - 存储服务:
文件存储,比如截图产生的图片,用户上传的apk文件,自动化测试的脚本等。 - 代理服务:
这里简单称之为代理服务,其实有多个服务,包括视频流转发服务、手势操作转发服务、远程调试转发服务、adb命令转发服务。主要是为设备被使用时的数据中转服务,因为远程控制数据量大且实时性要求高,所以不走web服务,通过WebSocket的方式独立提供服务。
运行效果
STF部署
上面所有的服务都可以是一台独立的电脑,也可以部分或全部在同一台电脑上。部署方式分为单机和集群两种。
单机
单机就是所有的服务都部署在同一台电脑上,用于自己使用。
stf的安装成功是比较困难的,命令其实很简单,主要是一些依赖库可能需要翻墙,因此建议下面的所有安装命令都要在翻墙状态下运行。安装失败建议卸载已安装的模块,全部重新安装。
安装:
首先,安装依赖项,Mac为例:
brew install rethinkdb graphicsmagick zeromq protobuf yasm pkg-config
然后再安装stf:
npm install -g stf
运行:
先启动rethinkdb:
只需要在命令行中通过rethinkdb命令启动;
再启动服务:
对于单机版,有一个快捷的命令以默认配置一键启动所有服务:
stf local --public-ip
—public-ip 是你的内网ip,这样局域网内的其他同学也可以远程你电脑上的手机,不加这个参数就只能本机访问。
使用:
默认的web服务端口是7100,因此在浏览器输入http://localhost:7100即可使用。
接入手机,设备列表上会自动出现手机并且标记为在线状态,点击该设备就可以进入远程控制状态;拔下手机就会自动标灰,无法远程。
集群
集群就是将部分模块独立部署,以缓解节点压力,上面的每一个服务都是可以独立部署的,并且像设备提供方、web服务器、代理服务器都是可以集群的。
一种简单的集群模式可以是:
将除设备提供服务外的所有服务部署在一个公网服务器上,而在每个人的电脑上部署一个设备提供服务。
这样,每个人电脑上的部署就相对简单,而且每个人都可以将自己电脑上的设备连接到服务器上,统一管理。
- 服务器部分:
因为不再是单机了,每个服务都得单独启动关联,相对复杂,可以参考官方的部署方法(https://github.com/openstf/stf/blob/master/doc/DEPLOYMENT.md) - 个人部分:
只要运行provider模块,所以只要使用stf provider命令,除了指定内网ip外(大家电脑上也没有公网ip),还需要其他几个必要参数,包括消息服务的地址、存储服务的地址、端口区间(用于代理服务分配端口,不能和其他设备提供方重合)等。完整的命令如下:
stf provider --name "%H/%i" --connect-sub tcp://devside.stf.example.org:7250 --connect-push tcp://devside.stf.example.org:7270 --storage-url https://stf.example.org/ --public-ip ${COREOS_PRIVATE_IPV4} --min-port=15000 --max-port=25000 --heartbeat-interval 10000 --screen-ws-url-pattern "wss://stf.example.org/d/%i///"
Docker部署
docker部署的成功率最高,但是在Mac下docker和宿主机无法共享USB设备,所以无法提供设备,其他其他的可以尝试。也在上面的官方部署里面有提到。
STF扩展方向
这里可以参考美团点评云真机平台实践(https://tech.meituan.com/2018/07/19/cloud-phone.html),可以扩展的方向包括:简单的页面改造、账户集成KMS、集成Jenkins自动化测试(使用API上传apk直接安装指定到测试机)、跨局域网部署(比如把Websocket换成WebRTC,使用SocketServer模拟设备转发)等等。反编译了阿里云真机的客户端程序源码,其真是通过本地开启了一个SocketServer中转云端真机的adb数据流,而我们本地Android Studio链接的设备其实是这个SocketServer,阿里云通过这个SocketServer实现了云真机的一些权限校验工作。
等实践了定制后再但单独开一篇介绍吧。