press 在操作时总是挂起是什么原因,如何解决这个问题

已存档
七月CX · 2 个月前
第 1 条补充
·
2 个月前

while(true){
if(text('确定').exists()&&!text('确认信息').exists()){
try{var a= text('确定').findOne();press(a.bounds().centerX(),a.bounds().centerY(),1);sleep(10);log("点击确定");}catch(e){log("1-1")}
}else if(text('确认信息').exists()&&!text('是').exists()&&!text('我知道了').exists()&&!text('无误').exists()){
log("w1")
try{var a= text('确认并支付').findOne();press(a.bounds().centerX(),a.bounds().centerY(),1);sleep(10);log("点击确定");}catch(e){log("1-2")}
}else if(text('是').exists()&&!text('我知道了').exists()&&!text('无误').exists()){
log("w2")
try{var a= text('是').findOne();press(a.bounds().centerX(),a.bounds().centerY(),1);sleep(10);log("点击确定");}catch(e){log("1-3")}
}else if(text('我知道了').exists()&&!text('无误').exists()){
log("w3")
try{var a= text('我知道了').findOne();press(a.bounds().centerX(),a.bounds().centerY(),1);sleep(10);log("点击确定");}catch(e){log("1-4")}
}else if (text('无误').exists()) {
log("w4")
try{
log(12)
text('无误').findOne().click()
break;
}catch(e){log(5)}
}
log("1")
sleep(100)
// try {
// // 检查确定按钮
// text('确定').findOne(10).click()
// } catch (e) {
// }
// try {
// // 检查确认信息并支付按钮
// text('确认信息并支付').findOne(10).click()
// } catch (e) {
// }
// try {
// // 检查就是这家按钮
// text('就是这家').findOne(10).click()
// } catch (e) {
// }
// try {
// // 检查自提门店不存在或未营业提示
// text('我知道了').findOne(10).click()
// continue
// } catch (e) {
// }
// try {
// // 检查确认无误按钮
// text('确认无误').findOne(10).click()
// } catch (e) {
// }
// log("1")
} 我在做这么一个循环点击操作,因为click点击动作有延时,想用press加快操作,但是脚本页面在没有人为干扰的情况下,press总是挂起,帮我找找原因

第 2 条补充
·
2 个月前

click的点击速度比press快么

回答

Hamibot AI
1
· 2 个月前

press 操作总是挂起可能由以下几个原因造成:

  1. 操作被中断:如果在执行 press 的过程中,用户自行触摸屏幕或触发了其他与屏幕交互的操作,会导致 press 执行失败并挂起。确保脚本运行时设备没有外部干扰。

  2. 长时间未完成:如果 press 设置的 duration 时间过长,而系统由于某些限制(如响应延迟)未能及时完成操作,也可能导致挂起。可以尝试减少 duration 值,确保其合理(例如 600ms 左右是常见推荐值)。

  3. 脚本逻辑问题:因为 press 是同步操作,只有在其完成时才会继续执行后续代码。如果你在 press 后依赖某些状态或操作,但这些内容未能正确满足条件,可能导致脚本看起来像是“挂起”。检查脚本逻辑是否需要异步处理或者添加超时机制。

  4. 设备性能或兼容性问题:部分设备或 Android 版本可能对自动化操作的支持有限。确保你的设备和 Hamibot 兼容,并且已按照文档要求开启所有必要权限(例如无障碍服务、悬浮窗等)。

  5. RootAutomator 或驱动问题:如果你使用 RootAutomator,请确认它已经正确启动并处于就绪状态。

解决方案

  • 确保 press 运行期间没有人为干预或外部事件。
  • 检查脚本逻辑,确认没有死锁或无限等待的情况。
  • 尝试缩短 duration 时间或换用 swipe/gesture 等替代操作。
  • 更新 Hamibot 到最新版本,以获得最新的功能和修复。
  • 如果问题持续存在,建议发送邮件到 support@hamibot.cn 提供详细信息,以便获取进一步支持。

你可以参考以下示例来测试 press 的基本行为:

// 文档地址 https://docs.hamibot.com/
press(500, 1000, 600); // 在 (500, 1000) 处按住 600 毫秒
toast("Press completed");

如果该测试能正常完成,则说明 press 功能本身没有问题,问题可能出在脚本逻辑或其他环境因素上。


补充回答 1

你的脚本中使用了 press 操作来替代 click,但发现 press 在执行时经常“挂起”,这通常是由以下几个原因造成的:


1. 坐标获取问题

你在代码中通过 bounds().centerX()bounds().centerY() 获取控件中心点。如果控件不可见(比如被其他控件遮挡)或已经被移除,那么获取的坐标可能是无效的,导致 press 无法正确执行。

建议:

  • 确保控件存在且可见。
  • 添加日志输出查看坐标值是否合理:
    var a = text('确定').findOne();
    log(`点击坐标: ${a.bounds().centerX()}, ${a.bounds().centerY()}`);
    

2. press 是同步操作,可能阻塞主线程

press(x, y, duration) 是一个同步操作,只有在按下完成之后才会继续执行后续代码。如果你设置的 duration 过长(比如 1000ms),或者系统响应较慢,会导致看起来像是“挂起”。

建议:

  • 缩短 duration 时间,例如设置为 100 毫秒即可模拟一次点击行为。
  • 如果需要更快速的操作,可以尝试直接使用 click()
    a.click();
    

3. RootAutomator 未启用或驱动不兼容

如果你没有使用 RootAutomator 或者 RootAutomator 没有正常运行,某些设备上 press 操作可能会失败或卡住。

建议:

  • 确保你已经调用 auto.waitFor() 并启用了 RootAutomator。
  • 在脚本开头添加:
    auto.waitFor();
    if (!RootAutomator.isRunning()) {
        toast("请确保 RootAutomator 已启动");
        exit();
    }
    

4. 线程阻塞或休眠时间不合理

你在每个循环中都加了 sleep(100),这个时间相对合理,但如果在关键路径上有过多 sleepfindOne() 超时等待,可能导致整体流程变慢甚至卡住。

建议:

  • 使用 findOne(timeout) 设置超时时间,避免无限等待:
    var a = text('确定').findOne(100); // 最多等待 100ms
    if (a) {
        press(a.centerX(), a.centerY(), 100);
    }
    
  • 避免在主线程频繁执行大量查找和操作逻辑,必要时可以拆分到子线程处理。

5. 脚本结构优化建议

你可以将重复逻辑封装成函数,减少冗余代码,并提高可读性:

// 文档地址 https://docs.hamibot.com/
function clickTextIfExist(textToClick, excludeTexts) {
    if (text(textToClick).exists()) {
        for (let exclude of excludeTexts) {
            if (text(exclude).exists()) return;
        }
        try {
            let target = text(textToClick).findOne(100);
            target.click(); // 或者使用 press
            log(`点击了: ${textToClick}`);
        } catch (e) {
            log(`点击失败: ${textToClick}`);
        }
    }
}

while (true) {
    if (text('确定').exists() && !text('确认信息').exists()) {
        clickTextIfExist('确定', []);
    } else if (text('确认信息').exists() && !text('是').exists() && !text('我知道了').exists() && !text('无误').exists()) {
        clickTextIfExist('确认并支付', []);
    } else if (text('是').exists() && !text('我知道了').exists() && !text('无误').exists()) {
        clickTextIfExist('是', []);
    } else if (text('我知道了').exists() && !text('无误').exists()) {
        clickTextIfExist('我知道了', []);
    } else if (text('无误').exists()) {
        clickTextIfExist('无误', []);
        break;
    }

    sleep(100);
}

总结

原因 解决方案
控件不可见或已失效 添加日志检查控件状态和坐标
press 同步操作导致阻塞 改用更小的 duration 或使用 click()
RootAutomator 未启用 检查并确保其正常运行
查找控件耗时过长 使用 `

补充回答 2

click() 的点击速度通常比 press(x, y, duration),原因如下:

✅ 1. click() 是异步操作

  • click() 是控件级别的操作,它由系统直接处理,通常是异步的。
  • 调用 click() 后脚本会立即继续执行下一行代码,不需要等待点击动画或系统反馈完成。

⚠️ 2. press() 是同步操作

  • press(x, y, duration) 是基于坐标的模拟点击,它是同步操作
  • 脚本必须等待整个 duration 时间结束后才会继续执行下一行代码。
  • 即使你设置 duration 为 1ms,仍然会有一定的线程调度和系统响应延迟。

✅ 3. 性能表现

  • 在大多数情况下,click() 更加高效,因为它更贴近 Android 的原生控件事件。
  • 如果控件是可点击的(如按钮、文字等),并且你可以通过控件查找 API 找到它,推荐优先使用 click()

🧪 示例对比

// 文档地址 https://docs.hamibot.com/
var btn = text('确定').findOne();

// 使用 click(),速度快,异步执行
btn.click();
log("click 已触发");

// 使用 press(),需要等待 100ms 才会继续执行
var x = btn.bounds().centerX();
var y = btn.bounds().centerY();
press(x, y, 100);
log("press 已触发");

✅ 推荐使用场景

方法 推荐使用场景
click() 控件存在且支持 .click(),例如按钮、TextView 等
press() 控件不可点击、无法通过控件方式操作时,或需要长按模拟

🔧 如果你想提升效率:

  • 优先使用 click()
  • 若必须使用 press(),可以尝试减小 duration(比如设为 50 ms)以减少阻塞时间。
  • 如果你在循环中频繁调用 press(),考虑是否可以通过多线程或 RootAutomator 提升效率。
ℹ️ 本回答由 AI 生成,内容仅供参考