if (step === 1) {
xdtimes = 0;
let root = auto.rootInActiveWindow();
if (!root) {
console.error("无法获取当前活动窗口");
sleep(1000);
return;
}
// 在当前窗口内查找按钮
let deliveryBtn = root.findOnce(textMatches(config.keywords.delivery).visibleToUser(true));
let storeBtn = root.findOnce(textMatches(config.keywords.store).visibleToUser(true));
if (deliveryBtn && storeBtn) {
if (clickOrder === 0) {
jitterClick(storeBtn, 3);
console.log("点击到店取");
} else {
jitterClick(deliveryBtn, 3);
console.log("点击送到家");
}
clickOrder = (clickOrder + 1) % 2;
// 重新获取根节点(防止窗口变化)
root = auto.rootInActiveWindow();
if (!root) {
console.error("窗口丢失,终止操作");
return;
}
// 在当前窗口内查找结果按钮
let saleoutBtn = null;
let confirmBtn = null;
let innerStartTime = new Date().getTime();
while ((new Date().getTime() - innerStartTime) < 300) {
saleoutBtn = root.findOnce(textMatches(config.keywords.saleout).visibleToUser(true));
confirmBtn = root.findOnce(textMatches(config.keywords.confirm).visibleToUser(true));
if (saleoutBtn || confirmBtn) break;
sleep(50); // 降低CPU占用
}
console.log("确认按钮:", confirmBtn);
console.log("售罄按钮:", saleoutBtn);
if (confirmBtn) {
console.log("找到确认按钮,准备点击");
if (config.maxnumtry === "a") {
let nummax = root.findOnce(className("android.widget.TextView").text("1").depth(25));
if (nummax) {
let bounds = nummax.bounds();
press(bounds.centerX() + 80, bounds.centerY(), 9);
}
}
jitterClick(confirmBtn, 3);
step = 2;
} else if (saleoutBtn) {
console.log("未找到库存,继续刷新操作..");
sleep(config.homeButtonInterval);
}
} else {
console.log("等待抢购(按钮未就绪)");
sleep(1000);
}
}
如何使用auto.rootInActiveWindow() 避免错误查找
回答
使用 auto.rootInActiveWindow()
可以确保你在当前活跃窗口中查找控件,避免因其他非目标窗口(如悬浮窗、状态栏等)干扰导致的错误查找。以下是一些建议和技巧,帮助你更好地利用 auto.rootInActiveWindow()
来提高查找准确性:
1. 每次操作前重新获取根节点
在执行关键操作前调用 auto.rootInActiveWindow()
获取最新的根布局对象,确保查找基于当前界面:
let root = auto.rootInActiveWindow();
if (!root) {
console.error("无法获取当前活动窗口");
return;
}
这样可以防止因界面切换或窗口变化导致的查找失败。
2. 限定查找范围
将控件查找限制在 root
范围内,而不是全局搜索,可以避免误触其他窗口的控件:
let deliveryBtn = root.findOnce(textMatches(config.keywords.delivery).visibleToUser(true));
let storeBtn = root.findOnce(textMatches(config.keywords.store).visibleToUser(true));
3. 结合 visibleToUser 提高准确性
加上 .visibleToUser(true)
过滤条件,确保找到的是用户可见的控件,减少隐藏控件干扰:
textMatches(config.keywords.delivery).visibleToUser(true)
4. 加入超时机制防止卡顿
对于需要等待出现的控件,可设定一个最大等待时间,避免无限循环:
let innerStartTime = new Date().getTime();
while ((new Date().getTime() - innerStartTime) < 300) {
saleoutBtn = root.findOnce(textMatches(config.keywords.saleout).visibleToUser(true));
confirmBtn = root.findOnce(textMatches(config.keywords.confirm).visibleToUser(true));
if (saleoutBtn || confirmBtn) break;
sleep(50);
}
5. 点击前再次确认控件存在
在点击控件前,再次检查控件是否有效,避免空指针异常:
if (confirmBtn) {
jitterClick(confirmBtn, 3);
step = 2;
}
6. 调试输出定位问题
打印调试信息有助于分析失败原因,例如:
console.log("确认按钮:", confirmBtn);
console.log("售罄按钮:", saleoutBtn);
7. 合理使用延迟与重试机制
适当增加 sleep()
时间或重试逻辑,应对界面加载延迟问题:
sleep(50); // 防止 CPU 占用过高
8. 避免跨窗口操作干扰
使用 auto.rootInActiveWindow()
确保始终操作当前界面,不会受到分屏、弹窗、悬浮窗的影响。如果你希望只针对特定窗口过滤,可结合 auto.setWindowFilter()
设置窗口筛选器。
通过以上方式,你可以更有效地使用 auto.rootInActiveWindow()
来避免错误查找,提升脚本稳定性。