脚本编写

Total Control 最大的优势之一就是其脚本编写功能。Total Control 提供了丰富的 API,可以控制一个或多个 Android 设备。它提供了两套 API:JavaScript 和 REST API。JavaScript 可以在本地运行脚本,REST API 则提供了语言和主机的灵活性。您还可以使用 REST API 来控制运行 "Total Control" 应用程序的多台计算机。

JavaScript API

语言

Total Control 提供以下 JavaScript 框架(ECMAScript 5,包括一些 ES6 特性):

  • 使用 Mozilla 的 Rhino 1.7.7(适用于 Total Control 7及以下版本),Rhino 1.7.12(适用于 Total Control 8)和 Rhino 1.7.14(适用于 Total Control 9,更新 20)。有关更多信息,请参阅https://github.com/mozilla/rhino
  • RingoJS 2.0。

Rhino 的优势在于可以直接调用 Java API(Total Control 8 使用的是 OpenJDK 15),如果 Rhino + RingoJS 提供的功能不足以满足需求。

Total Control 提供了许多类,以下是一些示例:

  • Device
  • DeviceArray
  • UiElement(Total Control 8)
  • UiElementArray(Total Control 8)
  • Notification
  • Keyboard
  • Excel

Device 和 DeviceArray 类

当设备连接时(自动连接或按下“连接”按钮),将创建一个来自“Device”类的设备对象,使用静态方法“searchObject”来定位设备对象。对于多个设备对象,它提供了“DeviceArray”类(从 Array 继承的子类)。DeviceArray 对象中的设备将同时执行相同的任务。

Device 类提供近 100 个方法和属性来操作设备。DeviceArray 类提供了大约 20 个常用方法。请参考 {{JavaScript API 文档}} 查看所有方法。您可以轻松扩展 Device 和 DeviceArray(请参阅扩展 Device 和 DeviceArray)。

使用“Device.searchObject()”来定位创建的设备对象,设备对象的格式为“device@<10位数字>”。

// 返回一个设备对象
var mySamsung = Device.searchObject('Samsung-S9');
// 返回所有设备对象,DeviceArray
var allDevices = Device.searchObject(tcConst.DevAll);
// 返回属于同一组的设备对象,DeviceArray
var allGroupX = Device.searchObject(tcConst.DevGroup, 'first row');
var allGroupY = Device.searchObject(tcConst.DevGroup, 'second row');
// 将两个组合成一个更大的组,DeviceArray
var groupXY = allGroupX.concat(allGroupY);

由于 DeviceArray() 是 Array() 的子类,它继承了 Array 类的大部分方法,由于所有 TC 特定的方法都与 DeviceArray 绑定,如果你有一个数组,请使用“var ary = new DeviceArray().concat(ary)”将其转换为 DeviceArray。

// 这会失败,因为 Array 中没有“click”方法
vardevice=Device.getMain();
varary=[device];
ary.click(100,100);

//Thiswillwork
vardevice=Device.getMain();
varary=newDeviceArray(device);
ary.click(100,100);    // or ary.clickSync("OK");

以下是一些示例:

// 点击设备名称为 "Samsung-S10" 的设备上的位置 (100,200)。
var device = Device.searchObject('Samsung-S10');
if (device) {
device.click(100,200); // or device.clickSync("Start");
}
var devices = Device.searchObject(tcConst.DevAll); if (devices) { devices.click(0.5, 0.5); // or device.clickSync("John"); }

目录和 Userlib.js

默认情况下,脚本目录位于 \Users\<用户名>\Documents\Scripts 目录下,您可以通过在主窗口中点击 "Script",选择 "Script List",并在顶部行更改目录。

在该目录下,您可以创建一个名为 "Userlib.js" 的文件,该文件将在脚本执行之前始终加载,您可以在其中包含常用函数、添加现有类的原型或引入第三方软件。

要调试 "Userlib.js",请使用 "Terminal",要重新加载 "Userlib.js",请点击底部右侧终端窗口的重新加载图标。

绝对坐标与相对坐标

对于 x、y 坐标,TC 提供了 "绝对" 和 "相对" 坐标(系统设置中显示的坐标会同时显示两种坐标),绝对坐标从 (0, 0) 到 (width – 1, height – 1),相对坐标通常是四位小数,从 (0, 0) 到 (0.9999, 0.9999)。将相对坐标乘以设备的宽度和高度将得到绝对坐标。坐标并非完美无缺,专业版支持 AAI,它使用 UI 元素中的文本来在运行时检索坐标。

扩展设备和设备阵列

JavaScript 的额外好处是可扩展性,您可以通过向类添加原型来扩展方法。假设您要为单个和多个设备创建一个名为"longPress"的方法,一种编写方法的方式如下:

Device.prototype.longPress=function(x,y){
	varretval=this.click(x,y,tcConst.STATE_DOWN);
	if(retval!=0){
		returnretval;
	}
	delay(500);
	returnthis.click(x,y,tcConst.STATE_UP);
}

DeviceArray.prototype.longPress=function(x,y){
	for(leti=0;i<this.length;++i){
		retval=this[i].longPress(x,y);
		if(retval!=0){
			returnretval;
		}
	}
	return 0;
}

这个实现对于包含大量设备的 DeviceArray 效率不高,如果阵列中有 100 个设备,该方法可能需要长达 50 秒。

更好的方法是先向所有设备发送 STATE_DOWN,然后等待剩余的 500 毫秒。幸运的是,Device 和 DeviceArray(多个设备)引入了"sendAll"方法,它执行指定的方法并等待指定的时间。这样,执行时间几乎为 500 毫秒。由于 "sendAll" 在 Device 和 DeviceArray 中都可用,因此 Device 和 DeviceArray 的代码实现完全相同。

Device.prototype.longPress=function(x,y){
	varretval=this.sendAll(Device.prototype.click,
	     [x,y,tcConst.STATE_DOWN],500);
	if(retval!=0){
		returnretval;
	}
	returnthis.sendAll(Device.prototype.click,[x,y,tcConst.STATE_UP]);
}

DeviceArray.prototype.longPress=Device.prototype.longPress;
 

"sendAll" 方法仅适用于成功返回 0 的方法。

脚本工具

Total Control 提供许多工具,点击 "Script" 将打开一个新窗口:

Terminal(终端):打开 Rhino + RingoJS 命令提示符,您可以在此进行测试或开发。点击右下方的按钮重新加载解释器和 Userlib.js。可以使用 load("filename.js") 来运行脚本。

脚本列表 ⇒ 路径:脚本默认路径,点击图标可更改为其他目录。

脚本列表 ⇒ JS 源文件:用于快速执行 JavaScript 文件,提供了一个简单的编辑器,可以快速修改或点击箭头键来执行脚本。

脚本列表 ⇒ 录制脚本:将设备上的操作记录到 Excel 文件中,Excel 文件还可以用于生成 JS 脚本或 JSON 文件(对于 REST API 可能有用)。没有 JavaScript 经验的用户可以使用此工具生成简单的脚本。

脚本列表 ⇒ 图片助手:从主设备屏幕内容生成 BMP 文件,该图像文件用于 seekImage(),它扩展了 BMP 文件以提供其他信息,如应用程序名称、活动、宽度和高度信息。seekImage() 将利用这些信息而无需提供大量参数。

脚本列表 ⇒ 颜色助手:从主设备加载屏幕内容(类似于图像助手),使用放大的颜色选择器选择颜色的 RGB 值,并生成 seekColor(),具有复杂参数。可以支持单个和多个颜色。

脚本列表 ⇒ UI 探测:打开 UI 探测窗口,点击截屏按钮捕获现有的主手机窗口,并允许用户使用查询语言选择 UI 元素。命令助手 窗口将为查询语言中的每个键提供帮助描述。

执行器(将更名为任务):创建一个任务,在各种条件下运行脚本,例如日期和时间、迭代次数、常规间隔或设备。任务执行的输出和结果将保存供查看。任务也可以通过 JS API 创建或更改。Runner 的执行将显示为任务。

检查:检查与脚本和引擎相关的各种内部变量。