

前言
大家好,我是鲫小鱼。是一名不写前端代码的前端工程师,热衷于分享非前端的知识,带领切图仔逃离切图圈子,欢迎关注我,微信公众号:《鲫小鱼不正经》。欢迎点赞、收藏、关注,一键三连!!
第七章:定时任务调度
一、理论讲解:定时任务的意义与原理
在自动化脚本开发中,定时任务调度是实现"无人值守"自动化的核心能力。无论是定时签到、定时备份、定时推送消息,还是周期性监控、批量处理,都离不开高效、可靠的定时调度机制。
1.1 定时任务的常见场景
每天定时自动签到/打卡/抢红包
定时备份数据、同步文件、上传日志
定时推送消息、提醒、通知
周期性监控App状态、自动重启
多账号/多任务批量定时执行
1.2 Auto.js 定时机制原理
通过 timers.setInterval/setTimeout 实现周期性/延时任务
结合 threads 多线程,实现主流程与定时任务并发
可与 Android AlarmManager、系统定时器结合实现更强大功能
支持自定义调度策略、任务优先级、动态调整
二、基础用法与代码示例
2.1 基本定时任务
javascript
复制代码
// 每隔10秒执行一次任务
timers.setInterval(function(){
toast("定时任务执行中");
}, 10000);
2.2 延时任务
javascript
复制代码
// 延时5秒后执行一次
timers.setTimeout(function(){
toast("延时任务已执行");
}, 5000);
2.3 多定时器并发
javascript
复制代码
// 启动多个定时任务
timers.setInterval(function(){
toast("任务A");
}, 5000);
timers.setInterval(function(){
toast("任务B");
}, 8000);
2.4 动态调整定时周期
javascript
复制代码
// 动态调整定时器周期
var interval = 10000;
var timerId = timers.setInterval(function(){
toast("动态周期任务");
}, interval);
// 5秒后调整周期
setTimeout(function(){
timers.clearInterval(timerId);
interval = 3000;
timerId = timers.setInterval(function(){
toast("新周期任务");
}, interval);
}, 5000);
2.5 定时任务与多线程结合
javascript
复制代码
// 子线程定时执行任务
threads.start(function(){
timers.setInterval(function(){
toast("子线程定时任务");
}, 7000);
});
2.6 定时任务与UI交互
javascript
复制代码
// 定时更新UI内容
"ui";
ui.layout(
);
timers.setInterval(function(){
ui.run(function(){
ui.clock.setText(new Date().toLocaleTimeString());
});
}, 1000);
2.7 定时任务的取消与重启
javascript
复制代码
// 启动和取消定时任务
var timerId = timers.setInterval(function(){
toast("循环任务");
}, 2000);
// 10秒后取消
timers.setTimeout(function(){
timers.clearInterval(timerId);
toast("定时任务已取消");
}, 10000);
2.8 定时任务与数据存储
javascript
复制代码
// 定时保存数据到本地
var count = 0;
timers.setInterval(function(){
files.write("/sdcard/autojs_count.txt", "计数:" + (++count));
}, 3000);
2.9 定时任务与网络请求
javascript
复制代码
// 定时请求接口并处理数据
timers.setInterval(function(){
http.get("https://api.github.com", {}, function(res, err){
if(err){
toast("请求失败");
return;
}
toast("状态码:" + res.statusCode);
});
}, 15000);
2.10 定时任务与异常处理
javascript
复制代码
// 定时任务加异常捕获,防止崩溃
timers.setInterval(function(){
try{
// 可能抛错的操作
toast("安全定时任务");
}catch(e){
log("定时任务异常:" + e);
}
}, 5000);
三、实战项目:定时自动打卡脚本
3.1 需求分析
每天早上8点自动打开App并打卡
支持手动一键打卡与定时自动打卡
支持打卡结果日志、异常处理、历史记录
支持UI界面配置打卡时间、App包名、打卡按钮文本
3.2 项目结构
plaintext
复制代码
autojs-clockin/
├── main.js
├── modules/
│ ├── clockin.js
│ └── logger.js
├── data/
│ └── history.json
├── ui/
│ └── config_ui.js
├── logs/
│ └── clockin.log
└── README.md
3.3 UI界面 config_ui.js
javascript
复制代码
"ui";
ui.layout(
);
ui.btnStart.on("click", () => {
threads.start(function(){
let res = require("../modules/clockin.js").run({
package: ui.package.text(),
btnText: ui.btnText.text()
});
ui.result.setText(res ? "打卡成功" : "打卡失败");
});
});
ui.btnHistory.on("click", () => {
let history = files.read("../data/history.json");
dialogs.alert("打卡历史", history || "暂无记录");
});
3.4 主入口 main.js
javascript
复制代码
// main.js
const config = require("./ui/config_ui.js");
const clockin = require("./modules/clockin.js");
const logger = require("./modules/logger.js");
// 定时调度函数
timers.setInterval(function(){
let now = new Date();
let target = ui.time.text().split(":");
if(now.getHours() == parseInt(target[0]) && now.getMinutes() == parseInt(target[1])){
logger.log("定时自动打卡开始");
clockin.run({
package: ui.package.text(),
btnText: ui.btnText.text()
});
}
}, 60000); // 每分钟检查一次
3.5 核心打卡逻辑 modules/clockin.js
javascript
复制代码
// modules/clockin.js
const logger = require("./logger.js");
function run(opt) {
logger.log(`启动App:${opt.package}`);
app.launch(opt.package);
sleep(5000);
if (text(opt.btnText).exists()) {
text(opt.btnText).findOne().click();
sleep(2000);
logger.log("打卡成功");
saveHistory(true);
return true;
}
logger.log("打卡失败");
saveHistory(false);
return false;
}
function saveHistory(success) {
let history = files.exists("../data/history.json") ? JSON.parse(files.read("../data/history.json")) : [];
history.push({ success, time: new Date().toLocaleString() });
files.write("../data/history.json", JSON.stringify(history, null, 2));
}
module.exports = { run };
3.6 日志模块 modules/logger.js
javascript
复制代码
// modules/logger.js
function log(msg) {
let line = `[${new Date().toLocaleTimeString()}] ${msg}`;
files.append("../logs/clockin.log", line + "\n");
toast(msg);
}
module.exports = { log };
四、分步详解与进阶技巧
4.1 多任务定时调度
支持多个定时任务并发执行
支持任务优先级、动态添加/删除/调整
4.2 定时任务与多线程结合
主线程调度,子线程执行任务,互不阻塞
支持任务超时、失败重试、异常捕获
4.3 定时任务与UI联动
定时更新UI内容、进度条、状态提示
支持定时推送消息、弹窗提醒
4.4 定时任务与数据存储
定时备份、同步、上传数据
定时清理缓存、日志、历史记录
4.5 定时任务与网络请求
定时同步远程数据、自动签到、自动打卡
支持失败重试、超时处理、结果推送
4.6 定时任务的取消与重启
支持一键暂停/恢复/重启定时任务
支持任务状态监控、日志记录
4.7 定时任务的异常与容错
try-catch 捕获异常,日志记录
任务失败自动重试、报警
4.8 定时任务的性能优化
合理设置周期,避免过于频繁
任务分批执行,避免资源争抢
日志分级输出,避免刷屏
任务队列+线程池提升并发效率
五、常见问题与解决方案
问题
解决方案
定时任务不准/丢失
检查 timers、线程、App 后台限制
多定时器冲突/卡顿
合理分配周期、优化任务粒度、使用线程池
定时任务崩溃/异常未捕获
try-catch 捕获异常,日志记录,自动重启
定时任务无法取消/重启
保存 timerId,及时 clearInterval/clearTimeout
定时任务与UI不同步
用 ui.run() 或 events 传递到主线程
定时任务执行慢/卡主线程
用子线程、异步处理耗时操作
定时任务日志无输出
检查日志路径、权限、输出逻辑
定时任务与数据存储冲突
加锁、队列、分片处理,避免并发写入
六、性能优化建议
合理设置定时周期,避免过于频繁
主线程只做调度,耗时任务用子线程/异步
定时任务加超时与重试,防止卡死
日志分级输出,开发阶段多输出,正式运行时降级
任务队列+线程池提升并发效率
定时任务异常自动重启,提升健壮性
合理 sleep,避免无效等待
任务状态监控,及时释放资源
任务分批执行,避免资源争抢
最后感谢阅读!欢迎关注我,微信公众号:《鲫小鱼不正经》。欢迎点赞、收藏、关注,一键三连!!!

