Auto.js 入门指南(九)自动处理弹窗与异常

260 阅读7分钟

前言

大家好,我是鲫小鱼。是一名不写前端代码的前端工程师,热衷于分享非前端的知识,带领切图仔逃离切图圈子,欢迎关注我,微信公众号:《鲫小鱼不正经》。欢迎点赞、收藏、关注,一键三连!!

第九章:自动处理弹窗与异常


一、理论讲解:弹窗与异常自动化的意义

在移动端自动化脚本开发中,弹窗、广告、异常提示是影响自动化流程稳定性的最大干扰因素。自动检测并处理弹窗、异常,不仅能提升脚本的健壮性,还能实现真正的"无人值守"自动化。

1.1 常见弹窗类型

  • 权限请求弹窗(如存储、定位、通知权限)
  • 广告弹窗、活动弹窗、更新提示
  • 网络异常、登录失效、系统错误弹窗
  • 二次确认、验证码、警告弹窗
  • App 内自定义弹窗、Dialog、PopupWindow

1.2 弹窗与异常的自动化难点

  • 弹窗文本、控件、结构多变,难以唯一定位
  • 弹窗出现时机不确定,需实时监控
  • 多种弹窗可能叠加、嵌套、遮挡主流程
  • 异常弹窗需区分"可忽略"与"需处理"
  • 误点风险,需精准识别

1.3 Auto.js 弹窗处理能力

  • 支持多线程/异步实时监控弹窗
  • 支持多种查找方式(text、desc、id、正则、模糊)
  • 支持批量处理、优先级处理、条件判断
  • 支持日志记录、异常上报、自动重试
  • 支持自定义弹窗规则、黑白名单

二、基础用法与进阶代码示例

2.1 实时监控并自动关闭弹窗

// 子线程实时监控弹窗
threads.start(function(){
    let popupTexts = ["关闭", "取消", "我知道了", "忽略", "不再提示", "以后再说", "同意", "允许"];
    while(true){
        popupTexts.forEach(txt => {
            let btn = text(txt).findOne(500);
            if(btn){
                btn.click();
                log("自动关闭弹窗:" + txt);
            }
        });
        sleep(1000);
    }
});

2.2 正则与模糊查找弹窗控件

// 正则查找所有"确定/OK/Yes"按钮
textMatches(/(确定|OK|Yes)/).find().forEach(btn => btn.click());

// 模糊查找包含"权限"或"广告"的弹窗
textContains("权限").find().forEach(node => node.click());
textContains("广告").find().forEach(node => node.click());

2.3 多层弹窗与嵌套弹窗处理

// 递归查找并关闭所有弹窗
function closeAllPopups(node) {
    if (!node) return;
    if (node.clickable() && /关闭|取消|忽略/.test(node.text())) {
        node.click();
        log("递归关闭弹窗:" + node.text());
    }
    for (let i = 0; i < node.childCount(); i++) {
        closeAllPopups(node.child(i));
    }
}
closeAllPopups(className("android.view.ViewGroup").findOne());

2.4 弹窗优先级与条件处理

// 优先关闭高危弹窗,再处理普通弹窗
let highPriority = ["危险", "警告", "异常", "登录失效"];
let normalPriority = ["广告", "活动", "推荐"];
highPriority.forEach(txt => {
    let btn = textContains(txt).findOne(500);
    if(btn) btn.click();
});
normalPriority.forEach(txt => {
    let btn = textContains(txt).findOne(500);
    if(btn) btn.click();
});

2.5 弹窗黑白名单与自定义规则

// 只处理白名单内的弹窗
let whitelist = ["关闭", "取消", "同意"];
whitelist.forEach(txt => {
    let btn = text(txt).findOne(500);
    if(btn) btn.click();
});

// 跳过黑名单弹窗
let blacklist = ["重要提示", "不可关闭"];
blacklist.forEach(txt => {
    let node = textContains(txt).findOne(500);
    if(node) log("跳过黑名单弹窗:" + txt);
});

2.6 弹窗处理日志与异常上报

// 记录弹窗处理日志
function logPopup(msg) {
    let line = `[${new Date().toLocaleTimeString()}] ${msg}`;
    files.append("/sdcard/popup.log", line + "\n");
    toast(msg);
}

// 异常弹窗上报(如推送到微信/邮箱)
function reportException(msg) {
    // 这里可集成第三方推送API
    log("异常上报:" + msg);
}

2.7 弹窗处理与主流程协同

// 主流程与弹窗处理线程协同
var popupThread = threads.start(function(){
    // ...弹窗处理逻辑...
});
// 主流程
for(let i=0;i<10;i++){
    toast("主流程第" + (i+1) + "步");
    sleep(2000);
}
// 结束时关闭弹窗线程
popupThread.interrupt();

2.8 异常捕获与自动重试

// 捕获异常并自动重试
function safeClick(selector, retry=3) {
    for(let i=0;i<retry;i++){
        try{
            let btn = selector.findOne(2000);
            if(btn){
                btn.click();
                return true;
            }
        }catch(e){
            log("点击异常,重试中..." + e);
        }
        sleep(1000);
    }
    return false;
}
safeClick(text("确定"));

三、实战项目:全局弹窗与异常自动处理器

3.1 需求分析

  • 实时监控全局弹窗、广告、异常提示
  • 支持多种弹窗类型、文本、控件、正则、模糊查找
  • 支持弹窗优先级、黑白名单、自定义规则
  • 支持日志记录、异常上报、自动重试
  • 支持主流程与弹窗线程协同、自动退出

3.2 项目结构

autojs-popupguard/
├── main.js
├── modules/
│   ├── popup_guard.js
│   └── logger.js
├── logs/
│   └── popup.log
└── README.md

3.3 popup_guard.js 代码

// modules/popup_guard.js
const logger = require("./logger.js");
const popupTexts = ["关闭", "取消", "我知道了", "忽略", "不再提示", "以后再说", "同意", "允许", "确定", "OK", "Yes"];
const highPriority = ["危险", "警告", "异常", "登录失效"];
const blacklist = ["重要提示", "不可关闭"];
function startGuard() {
    return threads.start(function(){
        while(true){
            // 优先处理高危弹窗
            highPriority.forEach(txt => {
                let btn = textContains(txt).findOne(500);
                if(btn){
                    btn.click();
                    logger.log("高危弹窗已处理:" + txt);
                }
            });
            // 处理普通弹窗
            popupTexts.forEach(txt => {
                let btn = text(txt).findOne(500);
                if(btn){
                    btn.click();
                    logger.log("弹窗已关闭:" + txt);
                }
            });
            // 跳过黑名单弹窗
            blacklist.forEach(txt => {
                let node = textContains(txt).findOne(500);
                if(node) logger.log("跳过黑名单弹窗:" + txt);
            });
            sleep(1000);
        }
    });
}
module.exports = { startGuard };

3.4 日志模块 modules/logger.js

// modules/logger.js
function log(msg) {
    let line = `[${new Date().toLocaleTimeString()}] ${msg}`;
    files.append("../logs/popup.log", line + "\n");
    toast(msg);
}
module.exports = { log };

3.5 main.js 代码

// main.js
const guard = require("./modules/popup_guard.js");
const logger = require("./modules/logger.js");

// 启动弹窗守护线程
var guardThread = guard.startGuard();

// 主流程示例
for(let i=0;i<10;i++){
    logger.log("主流程第" + (i+1) + "步");
    sleep(2000);
}
logger.log("主流程结束");
// 结束时关闭弹窗线程
guardThread.interrupt();

四、分步详解与进阶技巧

4.1 多线程弹窗监控

  • 主线程与弹窗线程分离,互不干扰
  • 支持多线程并发监控不同App、不同页面

4.2 正则、模糊查找与动态适配

  • 用 textMatches、textContains 提升弹窗适配率
  • 动态适配不同品牌、不同语言、不同版本弹窗

4.3 弹窗优先级与黑白名单

  • 高危弹窗优先处理,普通弹窗批量处理,黑名单弹窗跳过
  • 支持自定义弹窗规则、动态调整优先级

4.4 异常捕获与自动重试

  • try-catch 捕获异常,日志记录
  • 异常弹窗自动重试、报警、上报

4.5 日志记录与异常上报

  • 详细记录弹窗处理历史、异常信息
  • 支持推送到微信/邮箱/钉钉等第三方平台

4.6 主流程与弹窗线程协同

  • 主流程与弹窗线程互不阻塞,提升健壮性
  • 支持主流程结束时自动关闭弹窗线程

4.7 性能优化与资源释放

  • 控制弹窗线程数量,避免资源耗尽
  • 弹窗处理加超时,避免死循环
  • 日志分级输出,开发阶段多输出,正式运行时降级
  • 异步处理耗时操作,提升主流程响应
  • 定期清理无用变量、释放资源,降低内存占用

五、常见问题与解决方案

问题解决方案
弹窗找不到/误点检查控件属性、增加等待时间、优化查找方式
弹窗处理线程卡死/崩溃try-catch 捕获异常,日志记录,自动重启
多层弹窗/嵌套弹窗未处理用递归、分步处理、增加查找深度
黑名单弹窗误处理优化黑白名单规则,动态调整
异常弹窗未上报/日志丢失检查日志路径、权限、输出逻辑
弹窗处理与主流程冲突合理拆分主流程与弹窗线程,避免互相阻塞
误点导致主流程异常增加弹窗识别条件、日志回溯、异常捕获
资源泄漏/线程未释放线程退出及时释放资源,定期清理无用变量

六、性能优化建议

  • 控制弹窗线程数量,避免资源耗尽
  • 弹窗查找加超时,避免死循环
  • 优先级处理,提升高危弹窗响应速度
  • 日志分级输出,开发阶段多输出,正式运行时降级
  • 异步处理耗时操作,提升主流程响应
  • 定期清理无用变量、释放资源,降低内存占用
  • 合理 sleep,避免无效等待
  • 主流程与弹窗线程分离,提升健壮性

最后感谢阅读!欢迎关注我,微信公众号:《鲫小鱼不正经》。欢迎点赞、收藏、关注,一键三连!!!