怎么主动启动和停止一个进程
主动启动一个线程和停止一个线程
可以控制线程在什么时候启动和关闭吗而不是一起启动和关闭
回答
在 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 |