在handlers中使用函数调用了打开无障碍的auto()函数闪退了
如何在handlers方法中调用主线程方法
重写运行脚本方法是什么
回答
在 handlers 中调用 auto() 函数时闪退,是因为 auto() 函数需要在主线程中运行,并且它会抛出异常并跳转到无障碍服务启用界面。如果当前处于事件处理函数(例如按键监听、通知监听等)中,会导致脚本无法正常执行,从而出现闪退现象。
你可以改用 auto.waitFor() 函数来替代 auto(),因为 auto.waitFor() 会阻塞等待直到无障碍服务被用户手动开启,且不会导致异常跳转。但需要注意:auto.waitFor() 也不能在 ui 模式下运行。
示例代码如下:
// 文档地址 https://docs.hamibot.com/
auto.waitFor();
toast("无障碍服务已开启,脚本继续运行");
如果你是在监听事件中处理逻辑,可以考虑将耗时操作或开启无障碍服务的操作移到主线程中执行,避免在事件处理函数中直接调用相关函数。另外,确保你的脚本结构合理,不会因长时间的事件阻塞而导致崩溃。
补充回答 1
在 JavaScript 中,如果你希望在 handlers 方法中调用主线程方法,可以使用 ui.run() 或 threads.mainThread() 来确保代码在主线程中执行。
下面是一个示例,展示如何在 handlers 中调用主线程方法:
// 文档地址 https://docs.hamibot.com/
var handlers = {
    running: false,
    start: function () {
        if (this.running) return;
        this.running = true;
        // 调用主线程方法
        threads.mainThread().post(function () {
            toast('任务开始');
            // 执行需要在主线程中运行的任务
        });
    },
    stop: function () {
        if (!this.running) return;
        this.running = false;
        // 调用主线程方法
        threads.mainThread().post(function () {
            toast('任务停止');
            // 停止任务逻辑
        });
    }
};
在这个示例中,threads.mainThread().post() 用于将函数提交到主线程的事件队列中,确保操作是在主线程中执行的。
你也可以使用 ui.run(),它专门用于更新 UI 相关的操作:
ui.run(function () {
    toast('这是在主线程中执行的提示');
});
总结:
- 使用 threads.mainThread().post()可以在主线程中运行非 UI 操作。
- 使用 ui.run()更适合处理 UI 更新相关操作。
这样可以确保你在 handlers 中调用的方法正确地与主线程交互。
补充回答 2
在 Hamibot 中,如果你想重写运行脚本的方法,通常可以通过封装 engines.execScript() 来实现。这个函数允许你在新的脚本环境中执行一段脚本内容,并支持配置参数如延迟、循环次数、间隔等。
以下是一个可复用的运行脚本方法示例:
// 文档地址 https://docs.hamibot.com/
function runScript(name, script, config) {
    // 检查参数是否合法
    if (typeof name !== 'string' || typeof script !== 'string') {
        toast('脚本名称或内容不合法');
        return;
    }
    // 默认配置
    var defaultConfig = {
        delay: 0,
        loopTimes: 1,
        interval: 0
    };
    // 合并用户配置
    for (var key in config) {
        defaultConfig[key] = config[key];
    }
    // 执行脚本
    engines.execScript(name, script, defaultConfig);
}
// 使用示例
runScript('测试脚本', "toast('Hello World');", {
    loopTimes: 3,
    interval: 2000
});
功能说明
- name:脚本的名称,显示在任务管理中。
- script:要执行的脚本内容,作为字符串传入。
- config:运行配置项,包括:- delay:延迟执行时间(毫秒)。
- loopTimes:循环次数,设为- 0表示无限循环。
- interval:每次循环之间的间隔时间(毫秒)。
 
通过这种方式,你可以将运行脚本的逻辑统一在一个函数中,便于管理和扩展。你还可以根据需求添加更多功能,比如日志记录、异常处理等。