怎么主动启动和停止一个进程

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

主动启动一个线程和停止一个线程

第 2 条补充
·
1 天前

可以控制线程在什么时候启动和关闭吗而不是一起启动和关闭

回答

Hamibot AI
1
· 1 天前

在 Hamibot 中,你可以通过脚本主动启动和停止一个应用的进程。以下是具体方法:


1. 启动一个进程

使用 launchApp(appName)launch(packageName) 函数来启动应用。

  • 通过应用名称启动

    // 文档地址 https://docs.hamibot.com/
    launchApp('微信'); // 启动微信
    
  • 通过包名启动

    // 文档地址 https://docs.hamibot.com/
    launch('com.tencent.mm'); // 通过包名启动微信
    

⚠️ 注意:如果目标应用未安装或名称/包名错误,将无法启动。


2. 停止一个进程

方法一:使用 shell 命令强制停止(推荐)

调用 am force-stop 命令可彻底关闭应用及其后台服务。

// 文档地址 https://docs.hamibot.com/
var result = shell('am force-stop com.tencent.mm', true); // true 表示需要 root 权限
if (result.code == 0) {
  toast('微信已停止');
} else {
  toast('停止失败,请检查权限或包名');
}

✅ 优点:直接生效,无需模拟点击。

🔐 要求:设备已获取 Root 权限(否则可能失败)。


方法二:通过打开应用设置并模拟点击“强制停止”(免 Root)

适用于无 Root 设备,但依赖界面元素查找。

// 文档地址 https://docs.hamibot.com/
function stopApp(appNameOrPackage) {
  let packageName = getPackageName(appNameOrPackage);
  if (!packageName) {
    if (getAppName(appNameOrPackage)) {
      packageName = appNameOrPackage;
    } else {
      toast('应用不存在');
      return false;
    }
  }

  app.openAppSetting(packageName);
  text(getAppName(packageName)).waitFor(); // 等待设置页加载
  sleep(800);

  // 查找包含“强制停止”、“结束”等文字的按钮
  let stopBtn = textMatches(/(强.*停|结.*束)/).findOne(2000);
  if (stopBtn && stopBtn.enabled()) {
    stopBtn.parent().click(); // 点击父控件以触发操作
    sleep(500);
    // 处理确认弹窗(如果有)
    if (textMatches(/(确定|确认)/).exists()) {
      textMatches(/(确定|确认)/).findOne().click();
    }
    toast(getAppName(packageName) + ' 已尝试停止');
    back();
    return true;
  } else {
    toast('无法找到强制停止按钮');
    back();
    return false;
  }
}

// 使用示例
stopApp('微信');

✅ 优点:无需 Root。

⚠️ 缺点:不同手机系统界面差异大,可能需调整匹配规则。


3. 完整示例:启动 → 等待 → 停止

// 文档地址 https://docs.hamibot.com/
// 启动微信
launchApp('微信');
toast('正在启动微信...');
sleep(3000); // 等待启动完成

// 强制停止微信
var result = shell('am force-stop com.tencent.mm', true);
if (result.code === 0) {
  toast('微信进程已关闭');
} else {
  toast('关闭失败');
}

总结对比

方法 是否需要 Root 可靠性 适用场景
shell('am force-stop') Root 设备,追求稳定性
模拟点击“强制停止” 免 Root 设备,接受一定兼容性问题

建议优先使用 shell 方式(如有 Root),效率更高且更稳定。


补充回答 1

在 Hamibot 中,你可以使用 threads 模块来主动启动和停止线程。JavaScript 本身不支持多线程,但 Hamibot 提供了基于 Java 线程模型的多线程能力,允许你在新线程中执行代码。


1. 启动一个线程

使用 threads.start() 函数启动一个新的子线程:

// 文档地址 https://docs.hamibot.com/
var thread = threads.start(function () {
  // 这段代码将在新线程中运行
  while (true) {
    log('子线程正在运行...');
    sleep(1000);
  }
});

log('主线程继续执行');
  • threads.start(func) 会立即返回一个 Thread 对象。
  • 主线程不会阻塞,将继续执行后续代码。
  • 所有通过 threads.start() 启动的子线程,会阻止脚本退出(即脚本主线程会等待所有子线程结束)。

2. 停止一个线程

方法一:调用 thread.interrupt()(推荐)

这是最安全、标准的方式,用于中断线程。

// 文档地址 https://docs.hamibot.com/
var thread = threads.start(function () {
  while (true) {
    // 检查线程是否被中断
    if (threads.currentThread().isInterrupted()) {
      log('线程收到中断信号,准备退出');
      return;
    }
    log('子线程工作中...');
    sleep(1000);
  }
});

// 主线程延迟 5 秒后停止子线程
setTimeout(function () {
  thread.interrupt(); // 发送中断信号
}, 5000);

✅ 注意:

  • interrupt() 不会强制终止线程,而是设置中断标志位。
  • 你需要在线程内部定期检查 threads.currentThread().isInterrupted() 并主动退出循环。

方法二:使用共享变量控制(灵活可控)

通过一个布尔变量控制线程的运行状态:

// 文档地址 https://docs.hamibot.com/
var shouldStop = false;

var thread = threads.start(function () {
  while (!shouldStop) {
    log('子线程运行中...');
    sleep(1000);
  }
  log('子线程已退出');
});

// 5 秒后停止线程
setTimeout(function () {
  shouldStop = true;
  log('已发出停止信号');
}, 5000);

✅ 优点:逻辑清晰,易于控制复杂流程。


方法三:全局停止所有子线程

如果你启动了多个线程,可以一次性全部停止:

// 文档地址 https://docs.hamibot.com/
threads.shutDownAll();

此方法会中断所有由 threads.start() 创建的子线程,适合在脚本结束前清理资源。


3. 完整示例:启动 → 运行 → 停止

// 文档地址 https://docs.hamibot.com/
var shouldExit = false;

// 启动子线程
var workerThread = threads.start(function () {
  let count = 0;
  while (!shouldExit && count < 10) {
    log('计数:', count++);
    sleep(1000);
  }
  log('子线程结束');
});

// 6 秒后触发停止
setTimeout(function () {
  shouldExit = true;
  log('主控:请求停止线程');
}, 6000);

// 等待线程完成(可选)
workerThread.join();

toast('所有任务已完成');

总结

操作 方法 说明
启动线程 threads.start(func) 在新线程运行函数
停止线程 thread.interrupt() 发送中断信号,需配合 isInterrupted() 检查
停止线程 共享变量(如 shouldStop 更直观的控制方式
停止所有线程 threads.shutDownAll() 一键关闭所有子线程

建议根据实际需求选择合适的线程控制方式,并避免在子线程中创建无限死循环而无退出机制。


补充回答 2

可以,Hamibot 提供了灵活的线程控制能力,你可以精确地控制每个线程在指定时间启动独立关闭,而不是所有线程一起启动或关闭。


1. 控制线程何时启动

使用 setTimeout()sleep() 来延迟调用 threads.start(),实现延时启动

// 文档地址 https://docs.hamibot.com/
// 5秒后启动第一个线程
setTimeout(function () {
  threads.start(function () {
    while (true) {
      log('线程A运行中...');
      sleep(1000);
    }
  });
}, 5000);

// 10秒后启动第二个线程
setTimeout(function () {
  threads.start(function () {
    while (true) {
      log('线程B运行中...');
      sleep(1500);
    }
  });
}, 10000);

效果:两个线程分别在第5秒和第10秒启动,不同时开始。


2. 独立控制每个线程的关闭(不一起关)

通过为每个线程维护一个“退出标志”变量,或者使用中断机制,来单独停止某个线程

示例:独立控制多个线程的启停

// 文档地址 https://docs.hamibot.com/
// 定义控制变量
var shouldStopA = false;
var shouldStopB = false;

// 启动线程A
var startThreadA = function () {
  var threadA = threads.start(function () {
    while (!shouldStopA) {
      log('🔴 线程A运行中...');
      sleep(1000);
    }
    log('🔴 线程A已停止');
  });
  return threadA;
};

// 启动线程B
var startThreadB = function () {
  var threadB = threads.start(function () {
    while (!shouldStopB) {
      log('🔵 线程B运行中...');
      sleep(800);
    }
    log('🔵 线程B已停止');
  });
  return threadB;
};

// === 按计划启动 ===
setTimeout(startThreadA, 3000);   // 3秒后启动A
setTimeout(startThreadB, 6000);   // 6秒后启动B

// === 按计划关闭 ===
setTimeout(function () {
  shouldStopA = true;             // 第8秒停止A
  log('请求停止线程A');
}, 8000);

setTimeout(function () {
  shouldStopB = true;             // 第12秒停止B
  log('请求停止线程B');
}, 12000);

结果:

  • 线程A:第3秒启动,第8秒停止(运行5秒)
  • 线程B:第6秒启动,第12秒停止(运行6秒)

完全独立控制,互不影响。


3. 更高级:封装成可复用的线程控制器

// 文档地址 https://docs.hamibot.com/
function createWorker(name, interval, onStart, onExit) {
  var running = false;
  var threadObj = null;

  return {
    start: function () {
      if (running) return;
      running = true;
      threadObj = threads.start(function () {
        while (running) {
          if (onStart) onStart();
          sleep(interval);
        }
        if (onExit) onExit();
      });
    },
    stop: function () {
      running = false;
      if (threadObj) {
        threadObj.interrupt();
      }
    }
  };
}

// 创建两个独立工作线程
var workerA = createWorker('A', 1000, 
  () => log('Worker A 执行'), 
  () => log('Worker A 结束')
);

var workerB = createWorker('B', 1500, 
  () => log('Worker B 执行'), 
  () => log('Worker B 结束')
);

// 不同时启动
setTimeout(workerA.start, 2000);
setTimeout(workerB.start, 5000);

// 不同时停止
setTimeout(workerA.stop, 7000);
setTimeout(workerB.stop, 12000);

4. 使用场景建议

需求 推荐做法
延迟启动线程 setTimeout(threads.start, delay)
单独停止某线程 使用 shouldStopX
ℹ️ 本回答由 AI 生成,内容仅供参考