脚本不执行 — 逐步排查清单
分步排查清单
脚本"不执行"可能有很多表现:完全没反应、运行到一半报错、输出异常、自动退出。按以下顺序排查:
第一步:语法错误
检查控制台输出
脚本运行后 → 看控制台输出
有没有红色的 error 信息?
常见语法错误
// ❌ 常见错误 1:括号不匹配
if (condition { // 少了右括号
doSomething();
}
// ❌ 常见错误 2:分号不一定要但漏了大括号
if (condition)
doA();
doB(); // 实际只有 doA 在 if 内,doB 总是执行
// ❌ 常见错误 3:Rhino 不支持的语法
async function test() {} // Rhino 不支持 async/await
// 改用 Promise 或回调
// ❌ 常见错误 4:用了浏览器 API
document.getElementById(); // 没有 document!
fetch(...); // 没有 fetch!
// 改用 AutoJs6 的 http 模块
用代码编辑器检查
AutoJs6 代码编辑器会在语法错误处自动标红:
- 打开有问题的脚本
- 看编辑器里有没有红色波浪线
- 鼠标悬停查看具体错误提示
第二步:无障碍服务
检查服务状态
if (!auto.state) {
toast("无障碍服务未开启");
auto.openAutoSetting();
exit();
}
手动检查
设置 → 无障碍 → AutoJs6 服务是否开启?如果是关闭状态,重新开启。
第三步:权限缺失
逐项检查
// 悬浮窗
if (!floaty.checkPermission()) {
floaty.requestPermission();
}
// 屏幕捕获
// 调用 captureScreen 时会自动弹窗请求
// 所有文件访问(Android 11+)
if (!files.hasAllFilesAccess()) {
// 需要手动在 AutoJs6 抽屉里开启
}
AutoJs6 权限检查入口
AutoJs6 → 设置 → 权限 → 查看各项权限状态
第四步:控件找不到
现象
脚本运行了,但没做任何操作,控制台可能报找不到控件。
排查
// 1. 确认界面真的在前台
let pkg = context.getPackageName();
console.log("当前前台应用: " + pkg);
// 2. 控件是否存在
let btn = text("登录").findOne(3000);
if (!btn) {
console.error("没找到登录按钮!");
// 打印当前界面的控件树帮调试
dumpControlTree();
}
// 辅助函数:打印当前界面控件树
function dumpControlTree() {
let root = auto.getRoot();
function print(node, indent) {
let info = indent + node.className();
if (node.text()) info += ' text="' + node.text() + '"';
if (node.id()) info += ' id="' + node.id() + '"';
console.log(info);
let children = node.children();
for (let child of children) {
print(child, indent + " ");
}
}
print(root, "");
}
可能原因
| 原因 | 解决 |
|---|---|
| 界面还没加载完 | 加 sleep() 或 waitForActivity() |
| 控件在 WebView 里 | WebView 内部不可读,用坐标点击 |
| 选择器条件错了 | 用布局分析器重新定位 |
| 应用切走了 | 确认目标应用在前台 |
| 控件被遮挡 | 检查 visibility 属性 |
第五步:脚本启动方式
不同启动方式的行为差异:
| 启动方式 | 引擎 | 无障碍 | UI 界面 |
|---|---|---|---|
| 直接运行 | 当前引擎 | 继承 | 不关闭 |
| engines.execScript | 新引擎 | 继承 | 新建 |
| Tasker 触发 | 新引擎 | 可能需要确认 | 隐藏 |
| 定时调度 | 新引擎 | 可能需要确认 | 隐藏 |
| 打包 APK 启动 | 独立引擎 | 嵌入 APK 的无障碍服务 | 嵌入的 |
常见坑
// 坑:Tasker / 定时触发时 auto.waitFor() 不可省
"auto";
auto.waitFor(); // 定时触发时必须等无障碍就绪
// 坑:定时触发时 auto.state 可能是 false
if (!auto.state) exit(); // 先检查再执行
// 坑:打包 APK 后路径变了
// 不要用硬编码路径,用 files.cwd() 获取当前目录
let scriptDir = files.cwd();
第六步:版本兼容
AutoJs6 版本差异
// 某些 API 在不同版本可能不同
// v6.2+ 才有 WebSocketType
if (typeof WebSocketType === "undefined") {
console.error("需要 AutoJs6 v6.2 以上");
}
// v6.7 才有 auto.state 属性
// 老版本用 auto.enabled()
let autoOk = auto.state !== undefined ? auto.state : auto.enabled();
Android 版本差异
// Android 13+ 需要通知权限
if (device.sdkInt >= 33 && !notice.canNotify()) {
notice.requestPermission();
}
// Android 11+ 分区存储
if (device.sdkInt >= 30) {
files.requestAllFilesAccess();
}
第七步:Rhino 引擎陷阱
Rhino vs 浏览器
// ❌ Rhino 中不可用
// document, window, location, navigator
// fetch(), XMLHttpRequest()
// localStorage, sessionStorage
// async/await, Proxy, Symbol.iterator
// ✅ Rhino 中可用
// var, let, const, function
// if-else, for, while, switch
// console.log(), toast()
// http.get(), images.captureScreen()
// ui.layout(), ui.click()
调试 Rhino 兼容性
// 想试一个不确定的语法?直接在脚本里测试
try {
let result = "test".includes("t");
console.log("includes 支持: " + result);
} catch (e) {
console.log("includes 不支持: " + e.message);
}
第八步:运行内存 / OOM
现象
脚本运行一段时间后被系统杀死,日志里没有错误。
排查
// 检查内存状态
console.log("可用内存: " + device.getAvailableMemory() + " bytes");
// 图片用完必须 recycle!
let screen = images.captureScreen();
// ... 使用 screen ...
screen.recycle(); // ✅ 不要忘了
// Image 对象不会自动 GC!多了会 OOM
避免 OOM
// ❌ 错误:循环截图不释放
for (let i = 0; i < 100; i++) {
let screen = images.captureScreen();
// 使用...
// 没 recycle!循环几次就爆内存
}
// ✅ 正确:用完就释放
for (let i = 0; i < 100; i++) {
let screen = images.captureScreen();
// 使用...
screen.recycle(); // ✅
}
第九步:还是找不到原因?
1. 在 AutoJs6 应用 → 设置 → 开启"调试模式"
2. 再次运行脚本
3. 把完整的控制台输出复制出来
4. 在 GitHub Issues 中反馈