AutoJs6 中文文档 下载 App

事件循环与异步处理 — AutoJs6 中的并发模型

Rhino 不是浏览器

Rhino 没有浏览器那样的完整事件循环系统(Event Loop),也不提供 async/await。AutoJs6 在此基础上通过以下机制提供异步能力:

setTimeout 与 setInterval

AutoJs6 提供了全局版本的定时器函数:

// 延迟 1 秒执行
setTimeout(() => {
    toast("延迟执行");
}, 1000);

// 每 2 秒执行一次(无限循环)
let timer = setInterval(() => {
    console.log("定期执行: " + new Date().toLocaleTimeString());
}, 2000);

// 停止定时器
clearInterval(timer);

注意事项

engines 模块:多引擎并发

当你需要真正的并发执行时,engines 模块是正确选择——它可以启动新的脚本引擎实例,实现脚本间并行运行。

启动新引擎

// 启动一个新引擎执行脚本(异步)
let engine = engines.execScript(
    "后台任务",           // 引擎名称
    `
        console.log("我在后台运行");
        sleep(3000);
        console.log("后台任务完成");
    `,
    {                          // 可选配置
        delay: 1000,           // 延迟启动
        loopTimes: 3,          // 循环次数
        interval: 5000         // 循环间隔
    }
);

// engine 对象可以用来控制
console.log("引擎 ID: " + engine.id);
// engine.stop()      → 停止
// engine.kill()      → 强制终止
// engine.waitFor()   → 等待结束

引擎间通信

// 主引擎定义全局变量,子引擎可以访问
globalThis.sharedData = { counter: 0 };

let engine = engines.execScript("子引擎", `
    // 读取共享数据
    let data = globalThis.sharedData;
    data.counter++;
    console.log("计数器: " + data.counter);
`);

多引擎协作示例

// 主脚本:并行执行多个自动化任务

// 任务 A:自动签到
let taskA = engines.execScript("签到", `
    app.launchApp("签到应用");
    // ... 签到逻辑
`);

// 任务 B:自动清理
let taskB = engines.execScript("清理", `
    // ... 清理缓存逻辑
`);

// 等待两个任务都完成
engines.waitForAny([taskA, taskB]);
toast("至少一个任务完成了");

// 或等待全部完成
engines.waitForAll([taskA, taskB]);
toast("全部完成");

events 模块:系统事件监听

events 模块可以监听 Android 系统和应用的事件:

// 监听屏幕解锁
events.on("screen_unlocked", () => {
    console.log("屏幕已解锁");
});

// 监听按键事件
events.on("key", (keyCode, event) => {
    if (event.getAction() === event.ACTION_UP) {
        console.log("按键释放: " + keyCode);
    }
});

// 监听应用启动
events.on("app_launch", (pkg, activity) => {
    console.log("应用启动: " + pkg + "/" + activity);
});

事件类型清单

事件名触发时机回调参数
accessibility无障碍服务事件AccessibilityEvent
key物理按键事件keyCode, event
broadcast系统广播context, intent
app_launch应用启动pkg, activity
app_remove应用卸载pkg
notification通知收到Notification, pkg
screen_on/off/lock/unlock屏幕状态-
battery_changed电量变化-

Promise 与回调

Rhino 对 Promise 的支持有限,推荐使用回调风格:

// 回调式
function asyncTask(callback) {
    setTimeout(() => {
        callback(null, "任务完成");
    }, 1000);
}

asyncTask((err, result) => {
    if (err) {
        console.error("错误: " + err);
    } else {
        console.log("结果: " + result);
    }
});

常见陷阱

sleep 阻塞整个引擎

// ❌ 错误:会阻塞整个脚本引擎
sleep(5000);
// 这 5 秒内整个脚本都无法响应任何事件

// ✅ 正确:用 setTimeout 或分引擎
setTimeout(() => {
    // 这里的代码在延迟后执行,不会阻塞其他逻辑
}, 5000);

多引擎间不要共享 UI 操作

UI 操作(控件点击、滑动)应该在同一个引擎中完成。跨引擎并发做 UI 操作可能导致无障碍服务冲突。

定时器不会自动清理

如果脚本中有循环定时器但没有 clearInterval,即使脚本逻辑执行完了定时器仍会继续触发,直到引擎被销毁(应用退出或 engines.killAll())。