转载请注明出处:小锋学长生活大爆炸[xfxuezhang.cn]
背景介绍
autojs本身不支持暂停脚本,现有网上大部分最直接的做法就是在每条语句后面添加检查是否暂停。当脚本功能和代码量非常打的时候,每一条语句后面都加检测,未免不太现实。
这里我自己想到了一个极其方便的方法,但可能控制粒度会稍微大一点点,不过其实不影响的。效果示例:
暂停/启动功能
一般来说,代码都是模块化的,也就是以函数为单位。并且脚本是按照轮询来写的,以面对突发的意外界面。因此,大致框架为:
functiion main() {
func1()
sleep(xx);
func1()
sleep(xx);
func1()
sleep(xx);
// ...
funcN()
sleep(xx);
}
function func1() {
while(true) {
// do something: xxxxx;
mysleep(1);
if(xxx) {break;}
// ...
sleep(1);
}
}
function func2() {
// same as func1
}
// ...
function funcN() {
// same as func1
}
那么,实际上,我们可以改造sleep函数,间接实现暂停功能。改造如:
/**延时函数,可以实现伪暂停、超时重置等功能 */
var prev_pause_flag = null;
var pause_run = false;
function mysleep(t) {
if(prev_pause_flag==null || prev_pause_flag!=pause_run) {
prev_pause_flag = pause_run;
log(pause_run?"被暂停了...":"正在运行中...");
}
while(pause_run) {
sleep(500);
}
sleep(t);
}
这样,通过把脚本中所有的sleep改为mysleep,并且在需要的时候设置标志位pause_run,就可以实现脚本的暂停和启动了。用法与sleep一模一样,直接平替。
效果如图:
超时重启功能
事实上,通过略微改动,还可以实现脚本超时重启功能。一般超时检测是通过看门狗watch dog的机制。原理就是通过定时喂狗来保持运行,当一定时间内没有喂狗,就判定是超时,就可以重启了。
实现思路是,脚本一般不会在一个地方一直循环很久,如果是的话那很有可能就是卡住了。那么,只需要在调用mysleep时候,额外再判断一下当前执行的是什么功能,如果一定时间(或次数)内都是这个功能,那就判定为超时。参考实现如下:
/**延时函数,可以实现伪暂停、超时重置等功能 */
var prev_pause_flag = null;
var pause_run = false;
var prev_e_type = null;
var e_type_cntout = 0;
// 最大超时次数
var e_type_cntmax= 60;
function mysleep(t, e_type) {
if(prev_pause_flag==null || prev_pause_flag!=pause_run) {
prev_pause_flag =pause_run;
debug(pause_run?"被暂停了...":"正在运行中...");
}
while(pause_run) {
sleep(500);
}
sleep(t);
if(prev_e_type==null || prev_e_type!=e_type) {
e_type_cntout = 0;
prev_e_type = e_type;
}
e_type_cntout += 1;
if(e_type_cntout > e_type_cntmax) {
e_type_cntout = 0;
debug("超时了");
}
}
其中,e_type随便填,字符串也行。使用实例:
functiion main() {
func1()
sleep(1);
func1()
sleep(1);
func1()
sleep(1);
// ...
funcN()
sleep(1);
}
function func1() {
while(true) {
// do something: xxxxx;
mysleep(1);
if(xxx) {break;}
// ...
mysleep(1, "func1");
}
}
function func2() {
// same as func1
}
// ...
function funcN() {
// same as func1
}
那么,当func1中函数执行太久后,就会触发超时警告了。不过要注意e_type的使用时机!