news 2026/8/23 10:27:58

Auto.js 简介与避坑指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Auto.js 简介与避坑指南

Auto.js 是在 Android 平台上运行 JavaScript 脚本的工具,在自动化测试等方面非常有优势。本文探讨该项目的发展现状,为开发者应选择何种开源实现提供参考;探讨如何配置代码补全,提高 Auto.js 脚本编写的效率;本文也讨论 Auto.js 的局限性,结合笔者开发过程中遇到的问题,分析其原因,给出可行的解决方案。

Auto.js 的发展现状

Auto.js 由 hyb1996 于 2017/01/27 初次发布, 于 2020/03/13 因故停止维护, 最终版本名称为4.1.1 Alpha2, 构建版本号为461

原作者停止维护后,Auto.js 分为付费版免费开源版两种路线继续发展:

  • 付费版:原作者删除了开源的所有 Auto.js 代码,宣布继续开发闭源的收费版本,但目前所有版本都已经终止开发,不再维护。
  • 免费开源版:开源社区出现了多个 fork 版本,形成各自维护的局面,例如 TonyJiangWJ、kkevsekk1、 SuperMonster003、wilinz、aiselp 等作者均参与了其 fork 版本的维护。

基于种种考量,本文均使用 aiselp 作者开发的 AutoX v7.2.1。

配置代码补全,改善编程体验

Auto.js 的工具链不完善。很多开发者编写 Auto.js 时,只是依靠 VSCode 上的一个插件实现代码补全、项目管理、连接 ADB 设备等功能。然而,这个插件的自动补全功能有一些 bug 严重影响使用,ADB 连接也时常不稳定,出现断线问题。

可以用更好的方式实现代码补全。AutoX 的 GitHub 仓库中以 npm 包的形式提供了开发模板,每开启一个新项目时,用npm install安装依赖,npm 会自动下载autox-v6-api包,包内含有相关的.d.ts类型文件,以提供自动补全。

Auto.js 的代码补全在 AI 编程时代更加重要,因为 Auto.js 是小众平台,并没有大量的语料去训练 AI,中国大陆以外的地区甚至搜不到相关讨论。这导致 AI 在一些细节方面表现得不尽如人意。有了代码补全,人工改错的成本也会小一些。

至于“推送项目至手机”等功能,笔者目前自行编写批处理脚本实现,暂未找到更好的方法。

Auto.js 的局限性与避坑指南

Auto.js 使用 JS 作为脚本的语言,方便了无数开发者编写简单的脚本。但 Auto.js v6 选用 Rhino 作为在 Android 系统上执行 JS 的中间层,这引入了一些问题,例如 Rhino 并不完全支持 ECMA 规范,以及多线程支持的问题。

有限的const支持

以下代码在 Auto.js 的实际运行结果为,控制台打印了 10 次数字0

for(leti=0;i<10;i++){constindex=i;log(index);}

const改为let,问题解决,控制台打印了 0~9 的数字:

for(leti=0;i<10;i++){letindex=i;log(index);}

在 JS 规范中,每次循环都会创建一个新的块级作用域,const定义的常量只是在块级作用域中不能重新赋值,而不会影响下一次循环。但是 Auto.js 的运行结果显然不符合规范。

  • 问题的来源:Auto.js 使用 Rhino 运行 JS 脚本,Rhino 的 JS 实现并不完全符合规范:Rhino 中const具有函数作用域,而不是标准规定的块级作用域(block-scope)。2017 年就有开发者在 Rhino 的 GitHub 仓库中提交了关于这个问题的 issue,但 Rhino 至今没有修复完成。

  • 问题的普遍性:如果一个 JS 变量在作用域内不会被重新赋值,很多现代 IDE 和编辑器默认推荐使用const来定义这样的变量(不论在语义上,它是否是“常量”)。例如,ESLint 默认启用prefer-const规则,VSCode 中 for 循环的自动补全也默认使用 const,如果开发者使用了这些工具,就很容易中招。

  • 问题的隐蔽性:该问题不会产生报错。假设开发者想用 for 循环遍历一个ListView中的所有控件,出现问题时,实际却是每次循环都引用第一个控件,但没有任何报错或异常信息可以参考,非常难以排查。

如果需要在 Auto.js v6 环境下编写 for 循环,就需要注意避免使用const定义类似的变量。进一步地,在任何需要利用块级作用域特性的地方,都应该谨慎使用const定义变量。

多线程处理中的问题

JavaScript 采用事件循环机制运行,如果使用单一线程运行脚本,当脚本执行耗时操作时,整个线程将阻塞而无法处理其他事件;而 Auto.js v6 采用的 Rhino 引擎也不支持现代 JS 的异步函数。所以,需要使用 Auto.js 提供的“多线程”能力(实际上是一种模拟实现,JS 不支持多线程),将耗时操作放在单独的线程执行。

Auto.js 的文档写道:

通过threads.start()启动的所有线程会在脚本被强制停止时自动停止。

然而,对于有些多线程脚本,在 Auto.js 应用或打包的应用中点击“停止脚本运行”后,仍然会残留一些线程持续执行。下面是一个能够复现该问题的最小示例代码,运行这段代码一段时间后尝试停止脚本,程序仍然无限循环打印着“正在执行带 try 的线程轮询!”:

functionloopWithWhileTrue():void{threads.start(function(){while(true){try{log("正在执行带 try 的线程轮询!");sleep(3000);}catch(e){log(`捕获到异常:${e}`);}}});}functionmain():void{loopWithWhileTrue();}main();

去掉 try…catch 块,把脚本改写如下,该问题不再出现

functionloopWithWhileTrue():void{threads.start(function(){while(true){log("正在执行线程轮询!");sleep(3000);}});}functionmain():void{loopWithWhileTrue();}main();

查看 Auto.js 开源代码库,笔者了解到,在脚本强制停止时,每个线程会利用多种方式确保其已被停止,其中一种方式就是在线程内部抛出中止异常(InterruptedException),这样的异常经过序列化得到JavaException: com.stardust.autojs.runtime.exception.ScriptInterruptedException: null。上述出现问题的代码中使用了 try…catch 结构,中止异常被 catch 块捕获到,没有继续向上抛出,这可能使得全局的异常处理器无法感知这个 Exception,也无法控制线程停止运行。

按照这个猜想,修改脚本,对于所有未知的异常,全部继续向外层抛出

functionloopWithWhileTrue():void{threads.start(function(){while(true){try{log("正在执行带 try 的线程轮询!");sleep(3000);}catch(e){log(`捕获到异常:${e}`);throwe;// 向外层抛出未知异常}}});}functionmain():void{loopWithWhileTrue();}main();

经测试,强制终止脚本时,所有线程都可以正常停止。

这个问题带来的经验是,开发者要更加规范地使用catch机制。对于已知的异常,如 HTTP 错误等,可以在内层直接处理而不必向外抛出;对于未知异常,最好向外继续抛出直至变为 uncaught exception。这既能在早期发现问题,也避免了中断异常在线程内被catch处理,而不能发挥作用的情况。

如果因为种种原因,必须要把大部分异常都 catch 到,而不向外抛出,那么可以利用中断异常序列化后包含ScriptInterruptedException字符串的特性识别它,当识别到这种特殊的异常时向外抛出,或者主动终止线程:

functionloopWithWhileTrue():void{threads.start(function(){while(true){try{log("正在执行带 try 的线程轮询!");sleep(3000);}catch(e){log(`catch 到异常:${e}`);log(`异常类型是:${Object.prototype.toString.call(e)}`);if((easError).toString().includes("ScriptInterruptedException")){log("识别到脚本中断异常,向上 throw");throwe;// 或者不抛出,直接调用 threads.currentThread().interrupt()}}}});}

用序列化的值来判断异常,这显然违背了一些公认的软件工程原则,但在 Auto.js v6 环境中,这也是一种不得已而为之的变通方法。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/23 10:27:29

工业AGV多车路径规划:从轻量级算法到仓库落地实践

1. 项目概述&#xff1a;从网格世界到真实仓库的跨越几年前&#xff0c;当我第一次接触多智能体路径规划&#xff08;Multi-Agent Pathfinding, MAPF&#xff09;时&#xff0c;实验室里跑的都是“网格世界”&#xff08;Gridworld&#xff09;里的仿真。屏幕上&#xff0c;一个…

作者头像 李华
网站建设 2026/8/23 10:23:37

从文件到屏幕:Python/java 字符编码、解码、文本处理的底层逻辑解析

目录前言一、核心概念&#xff1a;编码、码点与字节流的三角关系1.1 Unicode 码点&#xff1a;字符的 “唯一身份证”核心特征1.2 编码规则&#xff1a;码点与字节的转换桥梁1.3 bytes 类型&#xff1a;Python 中的字节载体二、内存与存储&#xff1a;文本的 “两种形态”2.1 内…

作者头像 李华
网站建设 2026/8/23 10:22:39

OPTEE 3.15运行在QEMU ARMv8上

系统信息 uname -aLinux rtos 5.11.0-37-generic #41-Ubuntu SMP Mon Sep 20 16:39:20 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux Git配置 ~/.bashrc中开启git的调试模式 export GIT_TRACE_PACKET1export GIT_TRACE1export GIT_CURL_VERBOSE1git config --global user.email…

作者头像 李华
网站建设 2026/8/23 10:21:56

MiniMax H3前瞻:技术评估、部署准备与效果验证全指南

这次我们来看一个即将在GMI夏季峰会亮相的AI模型——MiniMax H3。从项目名称来看&#xff0c;这很可能是MiniMax公司继其MoE架构模型之后&#xff0c;推出的新一代高性能模型。对于关注大模型前沿动态和本地化部署可能性的开发者来说&#xff0c;这类新模型的发布总是值得关注的…

作者头像 李华
网站建设 2026/8/23 10:19:54

机器学习十大经典算法实战指南:从原理到数学建模应用

1. 项目概述&#xff1a;从“十大经典”到实战建模的桥梁 刚接触机器学习或数学建模的朋友&#xff0c;可能都听过“十大经典算法”这个说法。它像一份流传已久的“武功秘籍”&#xff0c;被无数教材、课程和论坛反复提及。但当你真正拿到这份名单&#xff0c;准备在数据挖掘项…

作者头像 李华
网站建设 2026/8/23 10:14:43

工业机器人Socket通信:3D视觉引导路径传输的完整协议设计与实现

如果你正在开发一个工业机器人应用&#xff0c;特别是涉及视觉引导的场景&#xff0c;那么“机器人通过Socket接收3D相机路径点位工艺文件并运行”这个需求&#xff0c;很可能就是你当前项目中最核心、也最容易出错的环节。这听起来像是一个简单的数据收发任务&#xff1a;相机…

作者头像 李华