为什么脚本不停止运行?

简介: 牙叔教程 简单易懂

牙叔教程 简单易懂


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

代码如下

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修改悬浮窗按钮点击事件
牙叔教程 简单易懂
1589 0
|
XML Android开发 数据格式
autojs一键锁屏
牙叔教程 简单易懂
663 0
|
Android开发
autojs之保活
autojs打包的app经常在后台被杀,请做到以下几点来保活: autojs版本号
2457 0
autojs之保活
|
Android开发
autojs用ConnectivityManager实现网络监听
autojs用ConnectivityManager实现网络监听
1398 0
|
存储 SQL 自然语言处理
基于 HBase 的海量数据查询与检索解析|学习笔记
快速学习基于 HBase 的海量数据查询与检索解析
基于 HBase 的海量数据查询与检索解析|学习笔记
|
自然语言处理 Java Go
Fury:一个基于JIT动态编译的高性能多语言原生序列化框架
Fury是一个基于JIT动态编译的多语言原生序列化框架,支持Java/Python/Golang/C++等语言,提供全自动的对象多语言/跨语言序列化能力,以及相比于别的框架最高20~200倍的性能。
Fury:一个基于JIT动态编译的高性能多语言原生序列化框架
|
10月前
一文带你封装Vue3 Echarts
一文带你封装Vue3 Echarts
864 7
一文带你封装Vue3 Echarts
|
12月前
|
资源调度 前端开发 测试技术
React Router 路由管理
【10月更文挑战第10天】本文介绍了 React Router,一个在 React 应用中管理路由的强大工具。内容涵盖基本概念、安装与使用方法、常见问题及解决方案,如路由嵌套、动态路由和路由守卫等,并提供代码示例。通过学习本文,开发者可以更高效地使用 React Router,提升应用的导航体验和安全性。
779 19
gorm 多对多关系 以及 关联的操作
gorm 多对多关系 以及 关联的操作
226 0
|
监控 持续交付 开发工具
软件配置管理与知识库管理实践
【8月更文第22天】软件配置管理(SCM)是在软件开发过程中为了确保项目的可追溯性和可控性而实施的一系列管理活动。它涵盖了版本控制、变更控制、发布管理和知识库管理等多个方面。本文将详细介绍这些关键领域的实践方法,并通过一个虚构的软件项目——“云笔记”应用程序为例来进行说明。
481 1

热门文章

最新文章