为什么脚本不停止运行?

简介: 牙叔教程 简单易懂

牙叔教程 简单易懂


群里有人提了个问题, 为什么脚本不停止运行?

代码如下

var thread;
var timer;
toastLog("脚本开始");
const delayBeforeCloseApp = 10;
thread = threads.start(function () {
  const start = new Date().getTime();
  timer = setInterval(() => {
    let diff = new Date().getTime() - start;
    if (diff < delayBeforeCloseApp * 1000) {
      const left = delayBeforeCloseApp * 1000 - diff;
      toastLog("剩余" + Math.floor(left / 1000) + "秒关闭应用");
    } else {
      clearInterval(timer);
    }
  }, 1 * 1000);
});
sleep(10 * 1000);
thread.interrupt();


运行日志如下


可以看到, 脚本确实没有停止运行


多打日志

var thread;
var timer;
toastLog("脚本开始1");
const delayBeforeCloseApp = 10;
thread = threads.start(function () {
  const start = new Date().getTime();
  timer = setInterval(() => {
    let diff = new Date().getTime() - start;
    if (diff < delayBeforeCloseApp * 1000) {
      const left = delayBeforeCloseApp * 1000 - diff;
      toastLog("剩余" + Math.floor(left / 1000) + "秒关闭应用");
    } else {
      log("清除定时器 start");
      clearInterval(timer);
      log("清除定时器 end");
    }
  }, 1 * 1000);
});
sleep(10 * 1000);
log("关闭多线程 start");
thread.interrupt();
log("关闭多线程 end");


再次运行上面的代码, 日志如下


可以看到多线程已经关闭了, 但是预期的清除定时器并没有打印出来


把定时器运行的时间设置的短一点, 比如5秒

var thread;
var timer;
toastLog("脚本开始1");
const delayBeforeCloseApp = 5;
thread = threads.start(function () {
  const start = new Date().getTime();
  timer = setInterval(() => {
    let diff = new Date().getTime() - start;
    if (diff < delayBeforeCloseApp * 1000) {
      const left = delayBeforeCloseApp * 1000 - diff;
      toastLog("剩余" + Math.floor(left / 1000) + "秒关闭应用");
    } else {
      log("清除定时器 start");
      clearInterval(timer);
      log("清除定时器 end");
    }
  }, 1 * 1000);
});
sleep(10 * 1000);
log("关闭多线程 start");
thread.interrupt();
log("关闭多线程 end");


运行日志如下


可以看到先清除定时器, 再关闭多线程, 脚本正常停止, 符合预期


那么, 可能引起问题的原因, 就是定时器没有正常关闭,

可能多线程关闭了之后, 定时器理论上应该跟着一起关闭,

但实际上, 定时器没有关闭, 或者说没有完全关闭,

导致脚本不能正常停止运行.

那怎么解决呢?

我们在关闭线程前面, 加一句关闭定时器

var thread;
var timer;
toastLog("脚本开始1");
const delayBeforeCloseApp = 10;
thread = threads.start(function () {
  const start = new Date().getTime();
  timer = setInterval(() => {
    let diff = new Date().getTime() - start;
    if (diff < delayBeforeCloseApp * 1000) {
      const left = delayBeforeCloseApp * 1000 - diff;
      toastLog("剩余" + Math.floor(left / 1000) + "秒关闭应用");
    } else {
      log("清除定时器 start");
      clearInterval(timer);
      log("清除定时器 end");
    }
  }, 1 * 1000);
});
log("延迟10秒 start");
sleep(10 * 1000);
log("延迟10秒 end");
log("清除定时器-主线程 start");
clearInterval(timer);
log("清除定时器-主线程 end");
log("关闭多线程 start");
thread.interrupt();
log("关闭多线程 end");


上面的代码, 运行日志如下


可以看到, 清除定时器-主线程, 关闭多线程都出来了, 但是脚本就是没有停止

猜想

是不是只能在启动定时器的多线程里面, 才能清除定时器啊?

在主线程清除定时器, 有没有办法?


我们在主线程里面加个定时器, 先停止Interval定时器, 再停止多线程

var thread;
var timer;
toastLog("脚本开始3");
const delayBeforeCloseApp = 10;
thread = threads.start(function () {
  const start = new Date().getTime();
  timer = setInterval(() => {
    let diff = new Date().getTime() - start;
    if (diff < delayBeforeCloseApp * 1000) {
      const left = delayBeforeCloseApp * 1000 - diff;
      toastLog("剩余" + Math.floor(left / 1000) + "秒关闭应用");
    } else {
      log("清除定时器 start");
      clearInterval(timer);
      log("清除定时器 end");
    }
  }, 1 * 1000);
});
log("延迟10秒 start");
sleep(10 * 1000);
log("延迟10秒 end");
log("清除定时器-主线程 start");
clearInterval(timer);
log("清除定时器-主线程 end");
setTimeout(() => {
  log("关闭多线程 start");
  thread.interrupt();
  log("关闭多线程 end");
}, 1000);


上面的代码, 运行日志如下


脚本正常结束


把setTimeout换成sleep试试

var thread;
var timer;
toastLog("脚本开始3");
const delayBeforeCloseApp = 10;
thread = threads.start(function () {
  const start = new Date().getTime();
  timer = setInterval(() => {
    let diff = new Date().getTime() - start;
    if (diff < delayBeforeCloseApp * 1000) {
      const left = delayBeforeCloseApp * 1000 - diff;
      toastLog("剩余" + Math.floor(left / 1000) + "秒关闭应用");
    } else {
      log("清除定时器 start");
      clearInterval(timer);
      log("清除定时器 end");
    }
  }, 1 * 1000);
});
log("延迟10秒 start");
sleep(10 * 1000);
log("延迟10秒 end");
log("清除定时器-主线程 start");
clearInterval(timer);
log("清除定时器-主线程 end");
sleep(1000);
log("关闭多线程 start");
thread.interrupt();
log("关闭多线程 end");


上面的代码, 运行日志如下

脚本正常停止

总结

关闭多线程之前, 应该确保多线程里面的定时器都正常关闭

名人名言


思路是最重要的, 其他的百度, bing, stackoverflow, github, 安卓文档, autojs文档, 最后才是群里问问
--- 牙叔教程


声明


部分内容来自网络
本教程仅用于学习, 禁止用于其他用途

相关文章
|
Android开发
autojs修改悬浮窗按钮点击事件
牙叔教程 简单易懂
1635 0
|
前端开发 JavaScript API
Layui的CRUD(增删改查)
Layui的CRUD(增删改查)
274 0
|
安全 Java Nacos
nacos常见问题之反序列化漏洞如何解决
Nacos是阿里云开源的服务发现和配置管理平台,用于构建动态微服务应用架构;本汇总针对Nacos在实际应用中用户常遇到的问题进行了归纳和解答,旨在帮助开发者和运维人员高效解决使用Nacos时的各类疑难杂症。
927 1
|
测试技术 API 开发工具
在Python中实现安卓手机自动化
在Python中实现安卓手机自动化
1765 0
|
6月前
|
jenkins 持续交付 开发工具
利用Dockerfile自主构建Jenkins镜像
希望这个过程能善用你的野马般想象,把自己置身于和计算机的卓尔不凡的对话中,让编程的过程充满趣味。
237 36
|
7月前
|
安全 Shell Linux
Linux系统之su命令的基本使用
Linux系统之su命令的基本使用
469 4
Linux系统之su命令的基本使用
|
SQL Java 关系型数据库
Java中的ORM框架——myBatis
Java中的ORM框架——myBatis
252 3
|
11月前
|
传感器 机器学习/深度学习 人工智能
AI视频监控卫士技术介绍:智能化河道管理解决方案
AI视频监控卫士系统,通过高清摄像头、智能传感器和深度学习技术,实现河道、水库、城市水务及生态保护区的全天候、全覆盖智能监控。系统能够自动识别非法行为、水质变化和异常情况,并实时生成警报,提升管理效率和精准度。
977 13
|
存储 数据采集 自然语言处理
知识图谱之《海贼王-ONEPICE》领域图谱项目实战(含码源):数据采集、知识存储、知识抽取、知识计算、知识应用、图谱可视化、问答系统(KBQA)等
知识图谱之《海贼王-ONEPICE》领域图谱项目实战(含码源):数据采集、知识存储、知识抽取、知识计算、知识应用、图谱可视化、问答系统(KBQA)等
知识图谱之《海贼王-ONEPICE》领域图谱项目实战(含码源):数据采集、知识存储、知识抽取、知识计算、知识应用、图谱可视化、问答系统(KBQA)等
|
存储 人工智能 物联网
端侧设备AI代理优化框架问世,领域内准确率可达97%
【7月更文挑战第30天】新框架Octo-planner提升端侧AI代理效率与准确性至97%。此框架由Nexa AI等机构合作研发,采用&quot;Planner-Action&quot;模式,将AI代理任务划分为规划与执行两部分,利用&quot;Octopus&quot;及&quot;Phi-3 Mini&quot;模型分别处理。通过fine-tuning技术及GPT-4辅助,实现在资源受限设备上的高性能。更多细节见论文: https://arxiv.org/pdf/2406.18082
337 1