等待页面跳转再执行下一条代码

wrekemdkwh · 1 天前
第 1 条补充
·
1 天前

我不确定下一个页面是什么

第 2 条补充
·
1 天前

使用while方法如果判断条件一直都是true,怎么实现停止这个方法

回答

Hamibot AI
1
· 1 天前

你可以使用 Hamibot 提供的 waitForActivitywaitForPackage 函数来等待特定页面(Activity)或应用出现后再执行后续代码。

1. 等待指定 Activity 出现

// 等待某个 Activity 名称出现,例如 "MainActivity"
waitForActivity("com.example.app.MainActivity", 200);
// 后续代码在此处继续执行
toast("已进入目标页面");

2. 等待指定应用界面出现(通过包名)

// 等待微信主界面出现
waitForPackage("com.tencent.mm", 200);
// 后续操作
toast("微信已打开");
  • waitForActivity(activity, period):等待指定的 Activity 被激活。
  • waitForPackage(package, period):等待指定包名的应用处于前台运行。
  • period 是轮询检查间隔时间,单位为毫秒,默认为 200 毫秒。

示例:启动应用并等待页面加载完成

// 启动微信
launchApp("微信");

// 等待微信主界面出现在前台
waitForPackage("com.tencent.mm");

// 继续执行下一步操作
toast("微信已就绪,开始自动化任务");

这种方式可以确保页面完全跳转后再执行下一条语句,避免因界面未加载完成而导致控件查找失败。


补充回答 1

如果你不确定下一个页面的具体 Activity 名称或包名,但仍然希望等待页面跳转完成后再执行后续代码,可以通过监听当前界面的关键元素变化来判断页面是否已切换。

推荐方法:使用 text()id() 等控件查找函数配合 waitFor 机制

// 示例:点击某个按钮后,等待新页面中出现特定文字
click("进入下一步");

// 等待新页面中的某个文本出现(可作为页面跳转成功的标志)
text("下一步操作说明").waitFor();

// 执行后续操作
toast("已到达新页面");

如果没有明确文本,可结合延迟和界面上下文判断

// 点击跳转
click("跳转");

// 先等待一小段时间让页面开始加载
sleep(1000);

// 尝试等待任意可能属于新页面的控件出现
// 比如“返回”按钮、标题栏等常见元素
back(); // 可尝试模拟一次返回,确认是否已进入新界面(谨慎使用)

// 或者用循环检测包名是否变化(适用于跨应用跳转)
var startTime = new Date().getTime();
while (currentPackage() === "com.example.oldapp") {
  sleep(200);
  // 防止无限等待
  if (new Date().getTime() - startTime > 5000) {
    toast("等待超时");
    break;
  }
}

toast("页面已切换");

使用 currentActivity()currentPackage() 主动监控

你可以在跳转前后打印当前上下文:

log("跳转前包名:", currentPackage());
log("跳转前Activity:", currentActivity());

// 执行跳转操作
click("跳转");

// 等待包名或 Activity 改变
while (currentActivity() === "com.example.old.MainActivity") {
  sleep(200);
}

toast("检测到页面已切换");

⚠️ 注意:使用这些方法时需确保 Hamibot 已获取无障碍服务权限,否则无法读取界面信息。

总结

当不知道目标页面具体信息时:

  • 优先等待新页面中独有的文本、ID 或控件
  • 结合 sleep + text(...).exists() 轮询检测
  • 使用 currentPackage() / currentActivity() 监听变化

这样可以稳定地“感知”页面跳转完成,无需预先知道目标页面名称。


补充回答 2

你可以使用 thread.interrupt() 方法来停止一个在 while(true) 死循环中运行的线程。

在 Hamibot 中,当你通过 threads.start() 启动一个子线程执行 while(true) 循环时,主线程会等待所有子线程完成。如果子线程没有退出条件,它将一直运行。为了能够主动停止这个循环,你需要保存 threads.start() 返回的 Thread 对象,然后调用其 interrupt() 方法来中断该线程。

示例代码:

// 文档地址 https://docs.hamibot.com/

// 启动一个子线程执行死循环
var thread = threads.start(function () {
    while (true) {
        log('子线程运行中...');
        sleep(1000); // 每秒输出一次
    }
});

// 主线程延时5秒后停止子线程
sleep(5000);
log('即将停止子线程');
thread.interrupt(); // 中断线程,此时 while 循环会退出

log('脚本结束');

说明:

  • thread.interrupt() 会中断目标线程。
  • 当线程被中断后,while(true) 循环会在下一次迭代时检测到中断状态并退出(尤其是在调用了 sleep() 等可中断方法时效果更明显)。
  • 如果你在循环中频繁调用 sleep()captureScreen() 等阻塞方法,它们会响应中断并抛出异常,从而使循环终止。

注意:如果你有多个子线程,也可以使用 threads.shutDownAll() 来一次性关闭所有由 threads.start() 创建的子线程。

批量关闭所有子线程示例:

// 文档地址 https://docs.hamibot.com/

var thread1 = threads.start(function () {
    while (true) {
        log('线程1运行中...');
        sleep(1000);
    }
});

var thread2 = threads.start(function () {
    while (true) {
        log('线程2运行中...');
        sleep(1000);
    }
});

sleep(5000);
log('准备关闭所有子线程');
threads.shutDownAll(); // 关闭所有子线程

log('所有线程已关闭');
ℹ️ 本回答由 AI 生成,内容仅供参考