auto.waitFor();
events.observeNotification();
events.on('notification', function (n) {
log(
'收到新通知:\n 标题: %s, 内容: %s, \n包名: %s',
n.getTitle(),
n.getText(),
n.getPackageName()
);
if(n.getPackageName()=="com.tencent.mm"){
log("可以点击");
n.click();
events.removeAllListeners('notification')
};
});
while(true){
sleep(5000)
log("5")
}
这么用, 监听为什么无法正常执行
如果我的主程序是一个循环 在这个循环中我想监听通知 符合条件的就进行点击 不符合条件的进行等待挂起,一旦点击后监听就停止,去执行其他操作,等待下一个循环再次开启监听 该怎么写
回答
你的代码存在几个问题会导致监听无法正常执行:
-
事件处理线程阻塞:你在监听通知的同时又有一个
while(true)
无限循环,这会阻塞事件线程。根据文档说明,事件处理是单线程的,原线程的耗时操作会影响事件处理。 -
监听器移除过早:在第一次收到微信通知后你就立即移除了所有监听器,这样后续通知就无法被处理了。
-
sleep使用:无限循环中的sleep会使线程挂起,进一步阻塞事件处理。
修改建议:
// 文档地址 https://docs.hamibot.com/
auto.waitFor();
events.observeNotification();
events.on('notification', function (n) {
log(
'收到新通知:\n 标题: %s, 内容: %s, \n包名: %s',
n.getTitle(),
n.getText(),
n.getPackageName()
);
if(n.getPackageName()=="com.tencent.mm"){
log("可以点击");
n.click();
// 只移除当前监听器而不是全部
events.removeListener('notification', arguments.callee);
}
});
如果你需要定时执行某些操作,建议使用定时器而不是无限循环:
setInterval(function(){
log("5");
}, 5000);
这样可以避免阻塞事件处理线程,让通知监听能够正常工作。
补充回答 1
以下是实现你需求的代码方案,通过合理的事件监听管理和循环控制来实现:
// 文档地址 https://docs.hamibot.com/
auto.waitFor();
function listenAndProcess() {
// 开启通知监听
events.observeNotification();
// 创建标志变量
var foundTarget = false;
// 定义监听函数
var listener = function(n) {
log(
'收到新通知:\n 标题: %s, 内容: %s, \n包名: %s',
n.getTitle(),
n.getText(),
n.getPackageName()
);
if(n.getPackageName() == "com.tencent.mm") {
log("找到目标通知,进行点击");
n.click();
foundTarget = true;
// 移除监听器
events.removeListener('notification', listener);
}
};
// 注册监听器
events.on('notification', listener);
// 等待直到找到目标通知
while(!foundTarget) {
sleep(500);
}
// 执行点击后的操作
log("点击完成,开始其他操作");
// 这里放你的其他操作代码
}
// 主循环
while(true) {
listenAndProcess();
// 这里可以添加循环间隔或其他控制逻辑
sleep(1000); // 示例:每秒检查一次
}
关键点说明:
- 将监听逻辑封装成函数
listenAndProcess()
- 通过标志变量
foundTarget
控制等待状态 - 找到目标通知后移除监听器并退出等待循环
- 在主循环中反复调用监听处理函数
- 使用短时
sleep(500)
避免完全阻塞事件处理
这样可以保证:
- 主循环正常执行
- 监听过程不会长期阻塞
- 找到目标后能立即处理
- 处理完成后继续循环