ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

AutoJs 4.1.0 Android自动化脚本入门:无障碍服务与控件选择器实战

AutoJs 4.1.0 Android自动化脚本入门:无障碍服务与控件选择器实战 我第一次听说“clsq客户端”这个名字时第一反应是某个内部工具后来被朋友拉到一起折腾才发现它背后真正有价值的东西其实是基于AutoJs 4.1.0的一套Android自动化脚本方案。AutoJs这个工具在国内Android圈子里名声很大它是一个把JavaScript和Android无障碍服务结合在一起的自动化引擎不需要root就能模拟点击、滑动、填表、读取界面控件被人称作“手机上的按键精灵”。今天我不讲任何灰色玩法就说清楚AutoJs 4.1.0到底是个什么东西、它的底层运行逻辑是什么、怎么装怎么配、怎么写第一个能跑的自动化脚本以及各种让人头大的坑。想用Android做自动化测试、做个人效率工具或者对无障碍机制感兴趣的朋友这篇文章应该能给你一个比较完整的起点。1. AutoJs 4.1.0 是什么以及它到底能干什么1.1 用一句话先建立认知AutoJs是一个运行在Android系统上的JavaScript自动化工具它的本质是一个APK应用应用内部内置了JavaScript引擎和一套封装好的Android自动化API。你写的每一行JS代码最终都会通过无障碍服务AccessibilityService转成系统级别的UI操作比如点击某个坐标、滑动屏幕、在输入框里填入文字、按返回键等。用生活化的比喻来说AutoJs就像给手机请了一个“看不见的机械手臂”而这个手臂的控制器是JavaScript脚本。你不用去改系统、不用刷机、也不用root只需要在系统设置里打开“无障碍服务”AutoJs就能读取当前屏幕的控件信息并且代替你的手指去操作手机。那么“clsq客户端”扮演什么角色从我们当时的项目实践来看它更像是一个基于AutoJs的定制化封装项目把AutoJs的脚本能力收进一个独立的客户端壳里对外提供更简洁的交互入口核心内核仍然是AutoJs 4.1.0那套运行机制。所以本质上你要理解这套东西学AutoJs准没错。1.2 在哪些场景里真正用得上我先把能说、且合规的典型使用场景列出来再看它的能力边界。第一类是自动化测试。App在上线之前经常要做反复的冒烟测试比如一直重复“点击登录-输入错误密码-查看提示-返回”这类工作让测试人员手工点几千次是很痛苦的。用AutoJs写一个循环脚本就能让手机自己去跑跑完输出日志方便判断有没有崩溃。第二类是个人效率工具。比如每天上班前自动打开某个办公App点进某个应用完成打卡操作又比如批量整理手机里的照片文件把特定目录下的文件按规则重命名、移动。AutoJs可以通过文件API操作本地存储配合界面自动化能做到“全自动流水线”。第三类是辅助Android开发者做界面调试。AutoJs自带“布局分析”功能能看到当前界面的控件树包括控件的id、text、desc、className等属性。这有点像Android Studio里的Layout Inspector但用起来更轻便不需要连接电脑直接在手机上就能看。不过AutoJs的边界也很清楚它不应该也最好不要被用来做破解、刷量、外挂、群控灰产等事情。这类行为既不稳定很容易被风控识别也有明确的合规风险。我后文所有示例都围绕“你自己设备上的、合规的、个人可操作的界面流程”来展开。1.3 4.1.0 这个版本有什么讲究AutoJs现在版本站有很多4.1.0是其中流传非常广的一个稳定版本。网上能看到大量基于这个版本的脚本和教程生态比较成熟。从技术角度说AutoJs 4.1.0有几个特点基于Rhino作为JavaScript引擎对ES5支持很完整ES6的部分特性也兼容但很多新语法比如箭头函数、async/await支持有限写脚本时尽量用ES5风格更稳。内置了强大的控件选择器API支持text、id、desc、className、bounds等属性组合查找这是它相比传统“坐标脚本”最大的优势。提供打包功能可以把你的JS脚本打包成独立APK做成一个不依赖AutoJs主程序的成品工具。基于Android目标版本比较老在Android 10以上系统可能存在文件权限、悬浮窗显示等兼容问题。现在社区里也有很多从AutoJs fork出来的分支项目比如AutoX.js、AutoJs6等它们主要是补齐了新版Android的适配API基本兼容。如果你想长期维护项目我建议你直接在AutoJs 4.1.0上把基础概念弄清楚再迁移到新分支也很容易迁移成本主要就是权限初始化那部分代码。2. 运行原理AutoJs 是怎么“看见”屏幕、执行操作的2.1 无障碍服务系统的“眼睛”和“手”要理解AutoJs绕不开“无障碍服务”这个概念。它原本是Android系统为视力障碍、肢体障碍用户设计的一套辅助能力比如屏幕朗读、焦点导航、手势替代等。对这个服务系统赋予了很高的权限它可以监听窗口变化、读取当前窗口的控件树、模拟手势操作。AutoJs做的事情就是以一个“无障碍服务”的身份运行在系统里。当你在脚本里写一句text(登录).click()时AutoJs会通过无障碍服务去查询当前界面上所有控件的属性找到一个text恰好是“登录”的控件节点再调用无障碍API对这个节点执行点击动作。这里有个关键点点击是控件级的不是像素级的。像素级脚本只是记录某个坐标点然后模拟触摸控件级脚本是根据UI控件属性动态寻找目标哪怕界面布局变了只要控件的text或id不变脚本依然能点对位置。这也是AutoJs比传统“脚本精灵”一类工具稳定得多的根本原因。当然如果你面对的是游戏画面、视频画面这种没有控件树的环境AutoJs就只能退回成像素级操作靠坐标和颜色识别来工作这就很不稳定了我在后面会说。2.2 JavaScript 运行环境与内置 APIAutoJs 4.1.0内部集成了Rhino引擎可以在Android上执行JavaScript。所谓“内置API”是AutoJs对这个JS环境做的扩展让脚本能调用Android系统和UI自动化相关的能力。比如最常用的一组API大致包括sleep(milliseconds)线程休眠控制操作间隔。toast(message)显示一个短暂的提示气泡。click(x, y)点击屏幕坐标。swipe(x1, y1, x2, y2, duration)模拟滑动。text(xxx)、id(xxx)、desc(xxx)、className(xxx)构建控件选择器。findOne(timeout)在当前界面查找符合条件的控件可以指定超时时间。launch(com.example.app)通过包名启动应用。readFile(path)、writeFile(path, content)读写文本文件。images.captureScreen()截图配合图像识别API可以做简单的找图、找色。这些API和原生Android开发中的Activity、Service、View体系联系非常紧密。如果你有Android开发经验看AutoJs的API会觉得很亲切如果完全没有那就把它当成一套“手机操控指令集”来记忆就好。2.3 存储与 content:// 的边界问题网上很多教程在讲AutoJs文件操作时会提到/storage/emulated/0/Android/data/这类路径或者content://形式的URI。这部分容易踩坑也特别容易产生合规性问题我单独说一下。content://是Android的ContentProvider机制用来跨应用共享数据。比如相册App可以让其他应用通过content://media/...访问图片文件管理器通过content://com.android.externalstorage.documents/...来浏览文件。AutoJs支持通过ContentResolver去查询和操作这些URI但注意它只能访问“该应用有权限访问的URI”。从Android 10开始系统强制分区存储每个应用只能方便地访问自己的专属目录和公共媒体目录第三方应用的Android/data目录限制非常严格。网上偶尔能看到一段“神奇脚本”宣称能读取微信、QQ、抖音等App的私有目录这种基本要么过时、要么靠root绕过要么涉及非常规授权路径。这里我不展开任何操作方法因为从合规和安全角度看都是高风险行为轻则被系统拦截重则涉及侵犯他人数据。我的建议很简单脚本里尽量只处理自己创建的目录和文件比如AutoJs自己的工作目录/sdcard/脚本/或者公共存储下的自定义文件夹。你在自己的设备上处理自己的文件这才是一个真实从业者该守住的底线。3. 安装配置与准备工作含 Android Studio 视角3.1 Apk 安装、权限开启与首次引导AutoJs 4.1.0的安装方式很传统下载APK包然后在手机上允许“安装未知来源应用”点击安装即可。装完后首次打开它会引导你开启两个关键权限无障碍服务和悬浮窗。无障碍服务在系统设置里的路径一般是“设置-辅助功能-已安装的服务-AutoJs”不同厂商ROM表述略有差异比如小米叫“无障碍-已下载的服务”华为在“辅助功能-无障碍”。你需要把对应的开关打开系统会弹一个“是否允许AutoJs监控您的操作并执行手势”的确认框这里必须点允许否则脚本跑不了。悬浮窗权限在安卓里通常叫“显示在其他应用上层”因为AutoJs的悬浮控制台、悬浮按钮都依赖这个权限。在MIUI、EMUI、ColorOS这类定制ROM里还需要额外把AutoJs设置为“允许后台弹出界面”、“允许自启动”否则手机息屏或后台清理时脚本会被干掉。按照我个人经验新手最容易卡的不是安装而是权限开启后没有真正生效。一个有效检查方法是打开AutoJs在控制台输入auto()并运行如果返回true并且悬浮窗出现说明无障碍服务已经正常连接如果报错再去设置里确认开关状态。3.2 用开发者选项辅助脚本调试我强烈建议你在开发调试阶段打开Android的开发者选项。具体路径是“设置-关于手机-连续点击版本号7次”然后在开发者选项里找到“指针位置”和“显示触摸操作”。开启指针位置后屏幕上会实时显示当前触摸点的坐标并且顶部状态栏会展示按压坐标值。这非常重要因为写坐标脚本时你不可能靠肉眼估算坐标有了指针位置功能你就能精确知道按钮在屏幕上的x和y值。“显示触摸操作”会以小白点和轨迹的方式展示每次触摸事件便于你观察脚本点击是否真的生效、点击位置是否偏了。对用AutoJs做“坐标型脚本”调试来说这两个开关能省掉大量时间。当然这只是辅助手段真正的自动化脚本不应该依赖坐标值来保证稳定而是应该优先使用控件选择器。坐标脚本只适合游戏、视频等没有UI控件的场景。3.3 AutoJs 与 Android Studio同源不同路很多接触Android开发的人会疑惑AutoJs和Android Studio有什么关系我的理解是AutoJs本质上是一个已经写好的Android工程项目它把JS引擎和无障碍服务封装好了你只需要在上面写JS脚本即可而Android Studio是更底层的Android原生开发环境你可以自己写一个类似AutoJs的应用。从学习角度你可以在Android Studio里打开AutoJs的开源分支项目看看它是如何注册AccessibilityService的如何把JS的click()方法映射到无障碍节点的performAction()调用。这一步对加深理解很有用但并不是写AutoJs脚本的前置条件。从工程落地角度AutoJs 4.1.0提供了“打包APK”的功能。你可以把写好的JS脚本打包成一个独立的Android应用安装到手机上直接运行而不需要先安装AutoJs主程序。打包出来的APK在首次启动时依然需要用户手动打开无障碍服务这是Android系统的安全要求任何应用都无法绕过。所以我的建议是如果你只是做自动化就直接在AutoJs上面写脚本如果你想把自动化能力做成产品那可以看Android Studio项目源码把AutoJs内核嵌入你自己的App里做好权限引导和UI界面这就是“clsq客户端”那类项目的技术路径来源。4. 手把手写第一个脚本坐标点击、控件选择与自动登录4.1 环境准备新建文件、运行脚本、查看日志打开AutoJs 4.1.0之后首页是一个文件管理器默认目录是/sdcard/脚本/。你可以点击右下角的“”新建一个JS文件取名叫hello.js然后编辑器会自动打开。AutoJs的脚本运行方式有两种直接在编辑器中点击“运行”脚本会在当前环境执行。通过悬浮窗上的按钮运行适合退出编辑器后用。日志查看入口在软件的抽屉菜单里叫“日志”。日志窗口会显示console.log()输出的内容也会显示脚本运行时的错误堆栈。写脚本时我习惯在关键节点打日志这是我排查问题的主要手段。第一次运行可以写一个最简单的脚本auto(); toast(hello autojs); console.log(脚本运行成功); sleep(2000);auto()的作用是请求无障碍服务权限检测服务是否可用。如果服务没开启运行到这里会弹出提示并自动跳转设置页。toast会在屏幕底部弹一个气泡“console.log”会把内容输出到日志面板。4.2 坐标操作click、swipe 与 sleep 的组合坐标操作是最直观的自动化方式。点击某个位置用click(x, y)滑动用swipe(x1, y1, x2, y2, 时长毫秒)。比如我想打开一个桌面上的App图标假设图标坐标是(540, 1200)可以写auto(); click(540, 1200); sleep(3000);这里的sleep(3000)非常关键。界面切换、页面加载都需要时间如果点击之后马上执行下一步操作大概率会因为控件还没出现而失败。通常我建议页面跳转后至少等2到3秒再继续操作。还有一个实用API是press(x, y, duration)它模拟“长按”比如长按图标触发编辑模式。坐标脚本写起来简单但缺点很明显换一台不同分辨率的手机所有坐标全部失效应用改版后按钮位置变了脚本也得跟着改。所以能用控件选择器的地方就尽量不要用纯坐标。4.3 控件选择器让脚本稳定复用控件选择器是AutoJs的灵魂。它的用法很直观先用text()、id()、desc()等函数描述你要找的控件再用.findOne()去查找找到后调用.click()执行点击。比如当前界面有一个按钮文本内容是“同意”我想点击它可以写auto(); var button text(同意).findOne(5000); if (button) { button.click(); console.log(点击了同意按钮); } else { console.log(没有找到同意按钮); }这里findOne(5000)的含义是在5秒内持续查找每100毫秒左右刷新一次控件树直到找到第一个符合条件的控件。如果超时还没找到会返回null所以要做空值判断否则下一行调用.click()会直接报错。desc()通常用于查找那些没有文本但有“内容描述”的控件比如图片按钮。id()则用于查找带资源ID的控件ID一般长成这样com.example.app:id/btn_login。AutoJs会自动识别当前前台App的包名所以写ID时可以直接去掉前面部分比如id(btn_login)。另外还有className(android.widget.Button)这种按控件类型查找的写法。实际开发中组合使用更有效比如var loginButton className(android.widget.Button).text(登录).findOne(3000);这样既限定了类型又限定了文本可以有效避免界面上存在多个“登录”文本的干扰。4.4 实战自动打开应用并完成一次登录下面我给出一个完整的实战示例场景很简单Android手机上安装了一个自己开发的测试应用包名是com.example.demo登录页有账号输入框、密码输入框、登录按钮。我们的目标是用AutoJs打开这个应用输入账号密码点击登录并判断是否登录成功。完整脚本如下auto(); // 启动应用 launch(com.example.demo); sleep(3000); // 查找账号输入框根据hint提示文本“请输入账号”定位 var accountInput hint(请输入账号).findOne(5000); if (accountInput) { accountInput.click(); accountInput.setText(testuser001); console.log(账号输入成功); } else { console.log(未找到账号输入框); exit(); } sleep(1000); // 查找密码输入框 var passwordInput hint(请输入密码).findOne(5000); if (passwordInput) { passwordInput.click(); passwordInput.setText(123456); console.log(密码输入成功); } else { console.log(未找到密码输入框); exit(); } sleep(1000); // 点击登录按钮 var loginBtn text(登录).findOne(5000); if (loginBtn) { loginBtn.click(); console.log(已点击登录); } else { console.log(未找到登录按钮); exit(); } // 等待页面跳转然后判断是否出现欢迎文字 sleep(4000); var welcome text(欢迎回来).findOne(2000); if (welcome) { console.log(登录成功已进入主界面); } else { console.log(登录可能失败请检查账号密码); }注意事项有几个setText()不是所有输入框都能生效部分自定义键盘或安全键盘会拦截这时候需要改用inputText()或者通过剪贴板粘贴的方式。账号密码这种敏感信息建议只在本地脚本里保存如果要发布给别人不要把明文密码写在脚本里否则会泄露。hint()查找方式是AutoJs提供的一个很实用的API专用于查找带placeholder提示文字的输入框比用className定位更可靠。5. 常见问题与排查经验5.1 无障碍服务频繁失效用户反馈最多的就是脚本跑着跑着突然没反应了打开设置一看AutoJs的无障碍服务被系统自动关闭了。这种情况在国内手机上尤其常见各种ROM为了省电和安全会把“长时间不使用的无障碍服务”自动回收掉。解决思路主要有三层第一在AutoJs内部设置里开启“保持唤醒”或“防止服务被回收”不同版本名称不同本质是申请后台运行权限。第二在系统设置里把AutoJs加入电池优化白名单禁止系统休眠时杀掉它。路径通常是“设置-电池-应用省电策略-选择不限制”。第三在最近任务列表里把AutoJs锁定避免用户或系统清理后台时把它划掉。除此之外个别ROM还有“读取已安装应用列表”权限、自启动权限等需要一并授权。做完这些之后稳定性会好很多但仍然不能保证100%不被系统回收所以脚本里最好做好异常重启机制。比如在脚本入口判断auto()返回值如果服务不可用就用toast提醒用户去开启。5.2 控件定位不到或选择器超时控件找不到几乎每个用AutoJs的人都会遇到。最常见的几个原因我按出现频率排序页面还没加载完控件不够5秒还没出现。解决方法是把findOne()的超时时间从5000改成10000或者先用sleep()做固定等待再查找。控件属性不对。有些按钮显示的文字不是存在text属性里而是存在content-desc里或者界面用了自定义View控件树里根本没有文本信息。这种要用AutoJs的布局分析功能看一下真实属性。目标App是网页内容运行在WebView里。WebView的控件树在无障碍服务下呈现得并不完整可能需要切换到accessibility模式或者用坐标方案兜底。屏幕上有弹窗遮住了目标控件比如登录页的隐私协议弹窗。这时候要先关闭弹窗再继续执行后续操作。排查技巧在脚本里捕获异常并打印控件树。AutoJs提供了currentPackage()获取当前前台应用包名currentActivity()获取当前Activity。你也可以用clickable()、editable()等方法去遍历当前页面的所有可点击控件把它们的文本信息全部打印出来再决定选择器怎么写。5.3 Android 版本差异与文件访问限制AutoJs 4.1.0发布时面向的系统还没那么新放到现在Android 10、11、12、13、14上都会遇到版本兼容问题。首先是文件路径。Android 10以前直接写/sdcard/xxx读文件没有问题Android 10以后应用要访问公共目录必须申请存储权限并且很多敏感目录访问会受到拦截。AutoJs 4.1.0在部分Android 11以上设备上会出现“无法读取本地文件”的报错原因是targetSdkVersion过低系统直接把它当作旧应用处理。社区给出的临时方案是手动去设置里给AutoJs授予“所有文件访问权限”路径是“设置-应用-AutoJs-权限-文件和媒体-允许管理所有文件”。其次是前台服务限制。从Android 8开始后台应用不能随便启动前台服务Android 12之后如果应用开启无障碍服务系统会频繁弹出“AutoJs正在运行”的通知这是正常现象不要关掉通知关掉可能导致服务被系统踢掉。第三是悬浮窗限制。在Android 10以上全屏展示时悬浮窗容易被系统自动隐藏需要手动点击“显示”按钮或者重新触发脚本的悬浮窗开关。如果发现悬浮窗按钮突然消失优先检查“显示在其他应用上层”权限是否仍然有效。5.4 调试技巧日志、截图与异常落盘我给AutoJs脚本做调试时最重要的三个习惯是多打日志、多次截图、异常落盘。多打日志不用多解释每执行完一个关键步骤加一条console.log()能快速定位脚本卡在哪一步。截图比日志更能还原现场AutoJs 4.1.0可以用images.captureScreen()抓取当前屏幕把它保存成文件var img images.captureScreen(); var time new Date().getTime(); images.save(img, /sdcard/脚本/screenshot_ time .png); img.recycle();异常落盘的意思是在脚本外层套一个try...catch把捕获到的错误堆栈写到本地日志文件中避免屏幕没盯着的时候丢失信息try { main(); } catch (e) { var logFile /sdcard/脚本/error.log; files.append(logFile, new Date().toString() e \n); toast(执行异常详情见日志); }这些习惯能在脚本上百次运行中帮你快速定位偶发问题而不是靠肉眼盯屏。6. 从 AutoJs 出去脚本打包、原生能力与 AI 扩展6.1 把脚本打包成独立 APK如果你的脚本给别人用让人家先装AutoJs再导入脚本体验很不好。AutoJs 4.1.0内置了打包功能打开脚本文件点击菜单里的“打包APK”设置好应用名称、图标、包名就能生成一个独立安装包。打出来的APK运行原理和AutoJs相同仍然需要无障碍服务授权但用户不需要理解JS、不需要碰脚本文件。这其实就是“clsq客户端”这类定制化客户端的一种做法里面跑的是AutoJs内核外面包了一层自己的产品外壳用户看到的是一个独立的App。打包的时候需要注意签名问题。生成APK时AutoJs默认会使用它的调试签名这种签名无法上架Google Play等正规渠道也不能用于覆盖安装已发布的正式包。如果要长期维护建议在Android Studio里把AutoJs内核工程拷出来换成自己的签名配置重新构建。6.2 脚本调用原生能力与 AI 模型的衔接AutoJs虽然强大但毕竟运行在JS层访问硬件和一些深度系统API时会有局限。这时候可以用AutoJs的adb命令配合或者在打包时通过Android Studio给应用增加原生模块由JS通过桥梁调用。举一个我实际探索过的方向在Android上本地运行AI大模型。现在社区里很流行用GGUF格式的量化模型配合llama.cpp在手机上跑AutoJs脚本可以做“调度层”负责监听界面变化、读取输入、把用户输入交给一个本地HTTP服务再由服务调用大模型生成结果最后把结果通过AutoJs的UI控件回填到界面里。脚本能力和AI能力的这个组合能解决不少真实场景的问题。具体到工程结构可以这样设计Android原生应用内置一个轻量级Web服务AutoJs用http.get(http://127.0.0.1:8080/api/generate?qxxx)发起请求拿到结果后再执行界面操作。AutoJs 4.1.0内置了http模块发送GET和POST请求都很方便。这类扩展的方向潜力很大但入口还是得先把AutoJs的基础原理吃透知道它哪能干、哪不能干才能把自动化脚本真正用对地方。最后分享一点我个人的体会使用AutoJs写脚本最核心的竞争力不在于API背了多少而在于你愿不愿意打开布局分析去读真实的控件树愿不愿意一遍遍调试、把每一个“偶尔失败”的原因都排查清楚。做自动化这件事一个人能写出来能跑的脚本不算本事能把脚本在不同系统、不同版本上都跑稳才算真正入了门。
返回列表