脚本引擎 - Engines
# Engines
> Stability: 2 - Stable
engines模块包含了一些与脚本环境、脚本运行、脚本引擎有关的函数,包括运行其他脚本,关闭脚本等。
例如,获取脚本所在目录:
```
toast(engines.myEngine().cwd());
```
## 运行脚本代码 | engines.execScript(name,script,config)
| 函数名 | 返回值 | 备注 |
| -------------------- | :-----------------: | ------------------------------------------------------------ |
| engines.execScript() | ScriptExectuion对象 | 在新的脚本环境中运行脚本script。 |
| **参数名** | **类型** | |
| name | 字符串 | 要运行的脚本名称。这个名称和文件名称无关,只是在任务管理中显示的名称。 |
| script | 字符串 | 要运行的脚本内容。 |
| config | Object | 运行配置项 |
engines.execScript(name, script[, config])
* `name` {string} 要运行的脚本名称。这个名称和文件名称无关,只是在任务管理中显示的名称。
* `script` {string} 要运行的脚本内容。
* `config` {Object} 运行配置项
* `delay` {number} 延迟执行的毫秒数,默认为0
* `loopTimes` {number} 循环运行次数,默认为1。0为无限循环。
* `interval` {number} 循环运行时两次运行之间的时间间隔,默认为0
* `path` {Array} | {string} 指定脚本运行的目录。这些路径会用于require时寻找模块文件。
在新的脚本环境中运行脚本script。返回一个[ScriptExecution](#engines_scriptexecution)对象。
所谓新的脚本环境,指定是,脚本中的变量和原脚本的变量是不共享的,并且,脚本会在新的线程中运行。
最简单的例子如下:
```
engines.execScript("hello world", "toast('hello world')");
```
如果要循环运行,则:
```
//每隔3秒运行一次脚本,循环10次
engines.execScript("hello world", "toast('hello world')", {
loopTimes: 10,
interval: 3000
});
```
用字符串来编写脚本非常不方便,可以结合 `Function.toString()`的方法来执行特定函数:
```
function helloWorld(){
//注意,这里的变量和脚本主体的变量并不共享
toast("hello world");
}
engines.execScript("hello world", "helloWorld();\n" + helloWorld.toString());
```
如果要传递变量,则可以把这些封装成一个函数:
```
function exec(action, args){
args = args || {};
engines.execScript(action.name, action.name + "(" + JSON.stringify(args) + ");\n" + action.toString());
}
//要执行的函数,是一个简单的加法
function add(args){
toast(args.a + args.b);
}
//在新的脚本环境中执行 1 + 2
exec(add, {a: 1, b:2});
```
## 运行脚本文件 | engines.execScriptFile(path,config)
| 函数名 | 返回值 | 备注 |
| ------------------------ | :-----------------: | ---------------------------------- |
| engines.execScriptFile() | ScriptExectuion对象 | 在新的脚本环境中运行脚本文件path。 |
| **参数名** | **类型** | |
| path | 字符串 | 要运行的脚本路径。 |
| config | Object | 运行配置项 |
engines.execScriptFile(path[, config])
* `path` {string} 要运行的脚本路径。
* `config` {Object} 运行配置项
* `delay` {number} 延迟执行的毫秒数,默认为0
* `loopTimes` {number} 循环运行次数,默认为1。0为无限循环。
* `interval` {number} 循环运行时两次运行之间的时间间隔,默认为0
* `path` {Array} | {string} 指定脚本运行的目录。这些路径会用于require时寻找模块文件。
在新的脚本环境中运行脚本文件path。返回一个[ScriptExecution](#ScriptExecution)对象。
```
engines.execScriptFile("/sdcard/脚本/1.js");
```
## 运行录制脚本 | engines.execAutoFile(path,config)
| 函数名 | 返回值 | 备注 |
| ---------------------- | :-----------------: | ---------------------------------- |
| engines.execAutoFile() | ScriptExectuion对象 | 在新的脚本环境中运行录制文件path。 |
| **参数名** | **类型** | |
| path | 字符串 | 要运行的录制文件路径。 |
| config | Object | 运行配置项 |
engines.execAutoFile(path[, config])
* `path` {string} 要运行的录制文件路径。
* `config` {Object} 运行配置项
* `delay` {number} 延迟执行的毫秒数,默认为0
* `loopTimes` {number} 循环运行次数,默认为1。0为无限循环。
* `interval` {number} 循环运行时两次运行之间的时间间隔,默认为0
* `path` {Array} | {string} 指定脚本运行的目录。这些路径会用于require时寻找模块文件。
在新的脚本环境中运行录制文件path。返回一个[ScriptExecution](#ScriptExecution)对象。
```
engines.execAutoFile("/sdcard/脚本/1.auto");
```
## 停止所有脚本 | engines.stopAll()
| 函数名 | 返回值 | 备注 |
| ----------------- | :----: | ------------------------------------------ |
| engines.stopAll() | | 停止所有正在运行的脚本。包括当前脚本自身。 |
engines.stopAll()
停止所有正在运行的脚本。包括当前脚本自身。
## 停止所有脚本显示数量 | engines.stopAllAndToast()
| 函数名 | 返回值 | 备注 |
| ------------------------- | :----: | ------------------------------------------------------------ |
| engines.stopAllAndToast() | | 停止所有正在运行的脚本并显示停止的脚本数量。包括当前脚本自身。 |
engines.stopAllAndToast()
停止所有正在运行的脚本并显示停止的脚本数量。包括当前脚本自身。
## 获取脚本引擎对象 | engines.myEngine()
| 函数名 | 返回值 | 备注 |
| ------------------ | :--------------: | -------------------------------------- |
| engines.myEngine() | ScriptEngine对象 | 返回当前脚本的脚本引擎对象ScriptEngine |
engines.myEngine()
返回当前脚本的脚本引擎对象([ScriptEngine](#engines?id=scriptengine))
**[v4.1.0新增]**
特别的,该对象可以通过`execArgv`来获取他的运行参数,包括外部参数、intent等。例如:
```
log(engines.myEngine().execArgv);
```
普通脚本的运行参数通常为空,通过定时任务的广播启动的则可以获取到启动的intent。
## 获取所有运行脚本引擎对象 | engines.all()
| 函数名 | 返回值 | 备注 |
| ------------- | :------------------: | -------------------------------------------------------- |
| engines.all() | ScriptEngine对象数组 | 返回当前所有正在运行的脚本的脚本引擎ScriptEngine的数组。 |
engines.all()
* 返回 {Array}
返回当前所有正在运行的脚本的脚本引擎[ScriptEngine](#engines_scriptengine)的数组。
```
log(engines.all());
```
## engines.startFloatingController(path[, config, options])
[Pro 9.1.10新增]
| 函数名 | 返回值 | 备注 |
| ------------ | -------- | -------------------- |
| engines.startFloatingController() | 布尔型 | 通过应用包名启动应用 |
| **参数名** | **类型** | |
|path|string|要运行的脚本路径。|
|config|Object|运行配置项,可选|
|delay|number|延迟执行的毫秒数,默认为0|
|loopTimes|number|循环运行次数,默认为1。0为无限循环。|
|interval|number|循环运行时两次运行之间的时间间隔,默认为0|
|path|Array|||string|指定脚本运行的目录。这些路径会用于require时寻找模块文件。|
|options|Object|悬浮控制器选项,可选|
|runImmediately|boolean|是否立即启动脚本引擎|
启动一个悬浮控制器(带有启动、暂停、日志等按钮),用于控制给定路径的脚本引擎的启动和停止。
# ScriptExecution
执行脚本时返回的对象,可以通过他获取执行的引擎、配置等,也可以停止这个执行。
要停止这个脚本的执行,使用`execution.getEngine().forceStop()`.
## 获取执行脚本引擎对象 | ScriptExecution.getEngine()
| 函数名 | 返回值 | 备注 |
| --------------------------- | :--------------: | ---------------------------------------- |
| ScriptExecution.getEngine() | ScriptEngine对象 | 返回执行该脚本的脚本引擎对象ScriptEngine |
ScriptExecution.getEngine()
返回执行该脚本的脚本引擎对象([ScriptEngine](#engines?id=scriptengine))
## 获取脚本配置 | ScriptExecution.getConfig()
| 函数名 | 返回值 | 备注 |
| --------------------------- | :----------: | -------------------------------- |
| ScriptExecution.getConfig() | ScriptConfig | 返回该脚本的运行配置ScriptConfig |
ScriptExecution.getConfig()
返回该脚本的运行配置([ScriptConfig](#engines?id=scriptconfig))
# ScriptEngine
脚本引擎对象。
## 停止脚本引擎的执行 | ScriptEngine.forceStop()
| 函数名 | 返回值 | 备注 |
| ------------------------ | :----: | -------------------- |
| ScriptEngine.forceStop() | | 停止脚本引擎的执行。 |
ScriptEngine.forceStop()
停止脚本引擎的执行。
## 停止脚本引擎的执行 | ScriptEngine.cwd()
| 函数名 | 返回值 | 备注 |
| ------------------ | :----: | ------------------------------------------------------------ |
| ScriptEngine.cwd() | 字符串 | 返回脚本执行的路径。对于一个脚本文件而言为这个脚本所在的文件夹;对于其他脚本,例如字符串脚本,则为`null`或者执行时的设置值。 |
ScriptEngine.cwd()
* 返回 {string}
返回脚本执行的路径。对于一个脚本文件而言为这个脚本所在的文件夹;对于其他脚本,例如字符串脚本,则为`null`或者执行时的设置值。
## 获取脚本引擎脚本对象 | ScriptEngine.getSource()
| 函数名 | 返回值 | 备注 |
| ------------------------ | :----------: | ------------------------------------ |
| ScriptEngine.getSource() | ScriptSource | 返回当前脚本引擎正在执行的脚本对象。 |
ScriptEngine.getSource()
* 返回 [ScriptSource](#engines_scriptsource)
返回当前脚本引擎正在执行的脚本对象。
```
log(engines.myEngine().getSource());
```
## 向该脚本引擎发送一个事件 | ScriptEngine.emit(eventName,args)
| 函数名 | 返回值 | 备注 |
| ------------------- | :----------: | ------------------------------------------------------------ |
| ScriptEngine.emit() | ScriptSource | 向该脚本引擎发送一个事件,该事件可以在该脚本引擎对应的脚本的events模块监听到并在脚本主线程执行事件处理。 |
| **参数名** | **类型** | |
| eventName | 字符串 | 事件名称 |
| args | any | 事件参数 |
ScriptEngine.emit(eventName[, ...args])
* `eventName` {string} 事件名称
* `...args` {any} 事件参数
向该脚本引擎发送一个事件,该事件可以在该脚本引擎对应的脚本的events模块监听到并在脚本主线程执行事件处理。
例如脚本receiver.js的内容如下:
```
//监听say事件
events.on("say", function(words){
toastLog(words);
});
//保持脚本运行
setInterval(()=>{}, 1000);
```
同一目录另一脚本可以启动他并发送该事件:
```
//运行脚本
var e = engines.execScriptFile("./receiver.js");
//等待脚本启动
sleep(2000);
//向该脚本发送事件
e.getEngine().emit("say", "你好");
```
# ScriptConfig
脚本执行时的配置。
## 延迟执行的毫秒数 | delay()
| 配置名 | 类型 | 备注 |
| ------ | :----: | ---------------- |
| delay | 整数型 | 延迟执行的毫秒数 |
delay
* {number}
延迟执行的毫秒数
## 循环运行间隔 | interval()
| 配置名 | 类型 | 备注 |
| -------- | :----: | -------------------------------- |
| interval | 整数型 | 循环运行时两次运行之间的时间间隔 |
interval
* {number}
循环运行时两次运行之间的时间间隔
## 循环运行次数 | loopTimes()
| 配置名 | 类型 | 备注 |
| --------- | :----: | ------------ |
| loopTimes | 整数型 | 循环运行次数 |
loopTimes
* {number}
循环运行次数
## 获取模块路径数组 | getPath()
| 配置名 | 返回值 | 备注 |
| ------- | :----: | ------------------------------------------------ |
| getPath | Array | 返回一个字符串数组表示脚本运行时模块寻找的路径。 |"
getPath()
* 返回 {Array}
返回一个字符串数组表示脚本运行时模块寻找的路径。
# 示例
## 停止所有正在运行的脚本
```js
engines.stopAllAndToast();
```
## 运行脚本文件
```js
var scriptsPath = "/sdcard/脚本/";
if(!files.exists(scriptsPath)){
scriptsPath = "/sdcard/Scripts/";
}
var scriptFiles = files.listDir(scriptsPath, function(name){
return name.endsWith(".js");
});
var i = dialogs.singleChoice("请选择要运行的脚本", scriptFiles);
if(i < 0){
exit();
}
var path = files.join(scriptsPath, scriptFiles[i]);
engines.execScriptFile(path);
```
## 运行录制文件
```js
var scriptsPath = "/sdcard/脚本/";
if(!files.exists(scriptsPath)){
scriptsPath = "/sdcard/Scripts/";
}
var scriptFiles = files.listDir(scriptsPath, function(name){
return name.endsWith(".auto");
});
var i = dialogs.singleChoice("请选择要运行的脚本", scriptFiles);
if(i < 0){
exit();
}
var path = files.join(scriptsPath, scriptFiles[i]);
engines.execAutoFile(path);
```
## 运行新的脚本任务
```js
var script = "toast('Hello, Auto.js');" +
"sleep(3000);" +
"toast('略略略');";
var execution = engines.execScript("Hello", script);
sleep(1000);
execution.getEngine().forceStop();
```