简介:本资源是面向Android自动化开发者的AutoJS实战案例合集,覆盖初学者入门到进阶应用的全场景需求,解决脚本编写缺乏参考、功能实现无从下手、第三方集成经验不足等核心痛点。压缩包共含大量.js源码文件,以JavaScript脚本为主,涵盖数据库操作、HTTP请求封装、主流第三方API调用(如天气、翻译、OCR)、全自动/半自动辅助工具(如抢红包、签到、群控)、JS加解密逻辑、手机传感器数据采集及轻量级小游戏Demo等模块,结构清晰、即拿即用。资源包大小为9.58MB,体积精炼但内容密度高,便于快速检索与本地调试。已有30566人学习下载,所有案例均由作者原创编写或经合规整理,不涉及版权风险,可放心用于学习研究、项目参考与功能复现。
1. 项目概述:从零到千的AutoJS实战宝库
最近在移动端自动化领域,AutoJS这个名字的热度一直居高不下。无论是开发者社区还是各种效率工具论坛,关于它的讨论总是层出不穷。我自己从几年前开始接触AutoJS,用它写过签到脚本、处理过重复性的表单填写、甚至做过一些简单的游戏辅助(当然是合规范围内的),深深体会到在Android设备上,有一个本地化、免Root的自动化工具是多么方便。所谓“AutoJS 1000案例 脚本代码大全”,听起来像是一个汇集了海量实战代码的“兵器谱”,其核心价值在于为学习者、开发者和效率追求者提供一个从入门到精通的“捷径”。它解决的正是新手面对空白编辑器无从下手,以及老手在实现特定复杂功能时寻找参考范例的痛点。无论你是想自动化一些日常App操作,还是希望深入学习JavaScript在移动自动化中的应用,这个案例库都能提供极具参考价值的模板和思路。
AutoJS本质上是一个基于JavaScript的Android平台自动化工具,它通过调用系统提供的无障碍服务(AccessibilityService)来模拟点击、滑动、读取屏幕内容,从而实现自动化操作。它的魅力在于“低门槛”和“高自由度”:你不需要复杂的开发环境,一部手机就能写代码、跑脚本;同时,JavaScript语言的灵活性又让你能实现非常复杂的逻辑。网络上流传的“1000案例”,正是这种自由度的集中体现,它覆盖了从基础控件操作到图像识别、从网络请求到数据处理等方方面面。接下来,我将结合自己多年的使用和教学经验,为你深度拆解如何构建、理解并高效利用这样一个案例库,让你不仅能“抄作业”,更能“出师”自己创造。
2. AutoJS核心能力与案例库架构解析
2.1 AutoJS的四大核心支柱
要理解上千个案例背后的逻辑,首先得摸清AutoJS的能力边界。它的所有功能都建立在几个核心支柱之上:
控件操作与信息获取:这是AutoJS最基础也是最常用的功能。它可以通过无障碍服务获取当前屏幕上的控件层级树(UI Hierarchy),从而定位到具体的按钮、文本框、列表项等。相关的核心函数是
className()、text()、id()等选择器,以及findOne()、find()、click()、setText()等方法。几乎80%的简单自动化案例都基于此。基于坐标的触控模拟:当控件无法通过常规方式定位时(例如游戏界面、自定义绘制控件),就需要退回到最原始的坐标操作。
click(x, y)、swipe(x1, y1, x2, y2, duration)、gesture()等函数允许你直接与屏幕坐标交互。很多游戏自动化或针对特定分辨率设备的脚本会大量使用此方式。图像与颜色识别:这是实现“所见即所得”自动化的关键。AutoJS内置了
images模块,可以截屏(captureScreen())、找图(findImage())、找色(findColor())。这对于识别验证码、判断特定图标是否出现、在游戏画面中定位怪物等场景至关重要。这部分案例通常涉及复杂的多分辨率适配和容错处理。设备控制与扩展能力:除了操作屏幕,AutoJS还能控制设备本身,如音量、亮度、震动(
device模块),执行Shell命令(shell()),访问文件系统(files模块),发送HTTP请求(http模块)。这使得脚本能做的事情远超UI自动化,例如自动备份文件、监控网络状态、与其他设备联动等。
一个高质量的“1000案例库”,必然会按照这四大能力维度进行组织,同时还会根据应用场景(如社交App、电商、游戏、工具类)进行横向分类。
2.2 案例库的典型内容架构
一个完整的案例库不会是一千个孤立的代码文件。它应该有清晰的层次结构,帮助用户循序渐进:
- 基础篇(约200例):涵盖环境搭建、基础语法、控件定位、简单点击循环。例如:“自动微信好友”、“定时打卡”、“一键清理后台”。
- 进阶篇(约300例):引入图像识别、多线程、配置文件读写、复杂手势。例如:“基于图像识别的游戏自动刷副本”、“多账号轮流登录执行任务”、“可配置参数的自动化脚本框架”。
- 高阶与综合篇(约400例):涉及网络请求解析、OCR集成(通过第三方插件)、复杂状态机设计、性能优化。例如:“自动爬取某新闻App每日推送并生成摘要”、“结合OCR识别图片中的文字并自动回复”、“使用
Promise和async/await管理复杂的异步自动化流程”。 - 工具与模板篇(约100例):提供常用的工具函数、项目模板、封装好的模块。例如:“分辨率自适应工具函数”、“日志记录模块”、“自动化任务队列管理器”、“优雅处理
autojs无障碍服务自动关闭的监控与重启模板”。
注意:网络上流传的案例合集质量参差不齐。很多代码可能针对旧版AutoJS或特定App版本,直接运行大概率会报错。一个真正有价值的案例库,应该附带详细的注释、运行环境说明(AutoJS版本号、Android版本、目标App版本)和核心逻辑的讲解。
3. 核心案例类型与实战代码深度拆解
下面,我将选取几个最具代表性的案例类型,不仅展示代码,更深入剖析其设计思路、潜在陷阱和优化技巧。
3.1 类型一:基于控件操作的自动化签到脚本
这是最普遍的需求。以“自动完成某论坛每日签到”为例,一个健壮的脚本需要考虑很多细节。
// 案例:某论坛自动签到脚本(增强版) let appName = “某论坛”; // 可配置 launchApp(appName); console.log(“已启动” + appName); sleep(3000); // 等待App启动 // 1. 寻找并点击“我的”选项卡 let myTab = className(“android.widget.TextView”).text(“我的”).findOne(5000); if (myTab) { myTab.click(); console.log(“已进入‘我的’页面”); sleep(2000); } else { console.error(“未找到‘我的’选项卡,可能界面已更新”); // 可以尝试备用方案:通过坐标点击 // click(屏幕宽度比例, 屏幕高度比例); exit(); } // 2. 寻找签到按钮或入口 // 优先使用多种选择器组合,提高容错 let signButton = text(“签到”).findOne(2000) || text(“每日签到”).findOne(2000) || className(“Button”).desc(“签到”).findOne(2000); if (signButton) { signButton.click(); console.log(“已点击签到按钮”); sleep(1500); // 3. 处理可能的弹窗(如签到成功提示、奖励弹窗) // 查找包含“成功”、“获得”、“确定”等字样的按钮并关闭 let closeButtons = textMatches(/成功|获得|确定|好的|知道了/).find(); for (let btn of closeButtons) { if (btn.clickable()) { btn.click(); sleep(500); } } console.log(“签到流程执行完毕”); } else { // 可能已经签到过了,检查是否有“已签到”文本 let signedText = text(“已签到”).findOne(1000); if (signedText) { console.log(“今日已签到,无需重复操作”); } else { console.warn(“未找到签到按钮,请检查页面布局或网络状态”); // 可以加入截图功能,便于后期排查 // captureScreen(“/sdcard/脚本日志/签到失败_” + new Date().getTime() + “.png”); } } // 4. 返回桌面或结束App(可选) // home(); // 返回桌面 // 更彻底的方式:结束App进程(需注意:这可能影响后台服务) // 根据热词`autojs结束app进程`,这是一个常见需求 if (false) { // 默认不开启,因为可能不必要 let packageName = getPackageName(appName); if (packageName) { shell(“am force-stop ” + packageName, true); console.log(“已结束” + appName + “进程”); } }实操心得与避坑指南:
- 等待与休眠的艺术:
sleep()的时间不是固定的。网络慢、手机卡顿都需要更长时间。更好的做法是使用waitFor()函数,在超时时间内循环检测某个元素是否出现,而不是死等固定秒数。 - 选择器的优先级与容错:不要只依赖
text()。控件的className、id(如果可用)、desc(内容描述)属性可能更稳定。使用findOne()时务必设置超时参数,避免脚本无限期卡住。 autojs无障碍服务自动关闭的应对:这是最令人头疼的问题之一。解决方案不是单一的。可以在脚本开头加入检查:if (!auto.service) { alert(“无障碍服务未开启!”); exit(); }。更高级的做法是写一个守护脚本,定时检查服务状态,如果关闭则自动跳转到设置页(通过app.startActivity()启动系统无障碍设置界面),但这需要用户授权,且不同手机厂商的设置路径不同,通用性是个挑战。通常,在社区中,建议用户将AutoJS的无障碍服务设置为“受保护的应用”,并在电池优化中忽略它,以减少被系统杀死的概率。- 结束进程的考量:
shell(“am force-stop ...”)能彻底结束App,但有些App结束后会收不到推送,或者再次启动时有漫长的启动页。是否结束进程应根据脚本目的决定。对于单纯的签到,或许不需要结束;对于需要清理环境进行多账号切换的脚本,结束进程则是必要的。
3.2 类型二:结合图像识别的游戏自动化脚本
当游戏界面没有标准控件时,图像识别是唯一的选择。以“自动点击游戏中的‘挑战’按钮”为例。
// 案例:基于图像识别的游戏按钮点击 requestScreenCapture(); // 1. 请求截屏权限 sleep(2000); let challengeButtonImg = images.read(“/sdcard/脚本资源/挑战按钮.png”); // 2. 读取模板图片 if (!challengeButtonImg) { console.error(“未找到模板图片,请检查路径”); exit(); } let maxRetries = 10; // 最大重试次数 for (let i = 0; i < maxRetries; i++) { console.log(“第” + (i + 1) + “次尝试识别…”); let screenshot = captureScreen(); // 3. 截取当前屏幕 let result = findImage(screenshot, challengeButtonImg, { // 4. 找图 threshold: 0.8, // 相似度阈值,0.8表示80%相似。游戏UI通常较稳定,阈值可设高 region: [0, 0, device.width, device.height * 0.8] // 限定搜索区域,提高效率 }); if (result) { console.log(“找到‘挑战’按钮,坐标:”, result); click(result.x + challengeButtonImg.width / 2, result.y + challengeButtonImg.height / 2); // 5. 点击中心点 sleep(1000); break; // 找到并点击后退出循环 } else { console.log(“未找到按钮,可能界面未加载,等待2秒后重试”); sleep(2000); // 这里可以加入一些备用操作,比如先点击一下屏幕中央防止熄屏 if (i % 3 == 0) click(device.width / 2, device.height / 2); } } if (i == maxRetries) { console.error(“多次尝试未找到按钮,脚本退出”); // 可以发送通知或记录日志 } challengeButtonImg.recycle(); // 6. 释放图片内存,重要! screenshot.recycle();图像识别实战要点:
- 模板图片的质量:模板图最好是从同一台设备、同一分辨率下截取的原始UI图,背景尽量干净。不要使用经过压缩或有水印的图片。
- 阈值(threshold)的调整:这是找图成功率的关键。UI元素固定时可用0.9以上;如果游戏特效导致颜色轻微变化,可降至0.7-0.8。需要通过反复测试确定最佳值。
- 区域(region)限定:全屏找图效率低下。如果按钮大概出现在屏幕下半部分,就限定搜索区域,能大幅提升速度和准确率。
- 多分辨率适配:你的脚本可能在不同分辨率的设备上运行。一种方案是准备多套模板图片;另一种更优的方案是使用“相对坐标”或“特征点匹配”。例如,不直接找按钮,而是先找一个更稳定的标志性UI(如游戏Logo),根据它的位置计算出按钮的大致区域,再进行找图。
- 内存管理:
images.read()和captureScreen()创建的图片对象会占用内存。在循环中或脚本最后,务必调用.recycle()方法释放,否则长时间运行的脚本可能导致内存不足而崩溃。
3.3 类型三:带配置与日志的复杂自动化框架
单个脚本功能有限,真正的生产力工具需要一个框架。下面展示一个简易可配置的多任务框架雏形。
// 案例:简易自动化任务框架 // —————— 配置文件 config.js —————— (可单独存放) var CONFIG = { tasks: [ { name: “论坛签到”, enabled: true, app: “某论坛”, script: “forum_sign.js” }, { name: “新闻阅读”, enabled: false, app: “新闻客户端”, script: “news_read.js” }, { name: “游戏日常”, enabled: true, app: “某游戏”, script: “game_daily.js”, timeout: 300000 } // 5分钟超时 ], global: { maxRetry: 3, logLevel: “INFO”, // DEBUG, INFO, WARN, ERROR screenshotOnError: true } }; // —————— 主运行脚本 main.js —————— files.ensureDir(“/sdcard/AutoScripts/logs”); let logger = (level, taskName, message) => { let time = new Date().toLocaleString(); let logMsg = `[${time}] [${level}] [${taskName}] ${message}`; console.log(logMsg); if (level === “ERROR” || level === “WARN”) { files.append(“/sdcard/AutoScripts/logs/error.log”, logMsg + “\n”); } }; for (let task of CONFIG.tasks) { if (!task.enabled) { logger(“INFO”, task.name, “任务已禁用,跳过”); continue; } logger(“INFO”, task.name, “开始执行”); let startTime = Date.now(); try { // 动态导入并执行子脚本 let taskScriptPath = “./scripts/” + task.script; if (files.exists(taskScriptPath)) { // 这里可以使用engines.execScript在子线程运行,避免阻塞 let taskFunction = require(taskScriptPath); if (typeof taskFunction === ‘function’) { taskFunction(task); // 将任务配置作为参数传入 } else { logger(“ERROR”, task.name, “脚本未导出为函数”); } } else { logger(“ERROR”, task.name, “脚本文件不存在: ” + taskScriptPath); } } catch (error) { logger(“ERROR”, task.name, “执行异常: ” + error); if (CONFIG.global.screenshotOnError) { let screenshot = captureScreen(); images.save(screenshot, `/sdcard/AutoScripts/logs/error_${task.name}_${startTime}.png`); screenshot.recycle(); } } let costTime = ((Date.now() - startTime) / 1000).toFixed(2); logger(“INFO”, task.name, “执行完毕,耗时 ” + costTime + “ 秒”); }框架设计思路:
- 配置与代码分离:将任务开关、参数等放在配置文件中,修改时无需动代码。
- 集中式日志管理:统一的日志函数方便记录和排查问题,特别是将错误日志写入文件,便于长期追踪。
- 异常捕获与容错:用
try...catch包裹每个任务执行,确保一个任务失败不会导致整个框架崩溃。 - 可扩展性:通过
require动态加载脚本,可以很方便地增删任务模块。可以考虑加入任务依赖、定时调度等功能。
4. 高级技巧与性能优化实战
当脚本越来越复杂,运行时间越来越长时,性能与稳定性就成为关键。
4.1 高效循环与等待策略
避免使用简单的while(true)和固定sleep。使用条件等待和智能间隔。
// 不推荐:低效的等待 while (!text(“任务完成”).exists()) { click(“下一步”); sleep(2000); // 固定2秒,可能太快或太慢 } // 推荐:条件等待与自适应间隔 function waitForElement(selector, timeout) { let start = Date.now(); while (Date.now() - start < timeout) { let element = selector.findOne(100); // 快速查找 if (element) return element; // 没找到,执行一些等待或保活操作 sleep(500); // 等待间隔稍长,减少CPU占用 if (!auto.service) throw new Error(“无障碍服务异常”); } return null; } let okButton = waitForElement(text(“确定”), 10000); // 等待10秒 if (okButton) { okButton.click(); } else { console.log(“等待超时,未找到确定按钮”); // 执行备用方案或退出 }4.2 多线程与事件处理
对于需要同时监控多个事件或执行后台任务的脚本,可以使用threads模块。
// 案例:后台监控网络状态,主线程执行任务 let networkMonitorThread = threads.start(function() { setInterval(() => { if (!device.isWifiConnected() && !device.isMobileDataConnected()) { console.warn(“[监控线程] 网络连接断开!”); // 可以在这里触发通知,或设置一个全局标志位 global.networkLost = true; } else { global.networkLost = false; } }, 5000); // 每5秒检查一次 }); // 主线程任务 for (let i = 0; i < 100; i++) { if (global.networkLost) { console.error(“主任务因网络中断暂停”); networkMonitorThread.interrupt(); // 中断监控线程 break; } // 执行主要的点击、滑动操作... console.log(“执行第” + i + “步”); sleep(1000); } networkMonitorThread.join(); // 等待监控线程结束(如果没被中断)重要提醒:多线程编程需谨慎。共享变量(如
global.networkLost)可能引发竞态条件。AutoJS的线程模型相对简单,复杂的线程同步可能不支持。通常,只将简单的、独立的后台任务(如监控、计时)放在子线程。
4.3 内存与资源泄漏排查
长时间运行的脚本可能因为内存泄漏而崩溃。主要检查点:
- 图片对象:确保所有
images.read()、captureScreen()创建的Image对象,在使用后都调用了.recycle()。 - 定时器:
setInterval()一定要在不需要时用clearInterval()清除。 - 循环引用:在复杂的对象结构中避免A引用B,B又引用A的情况,这可能导致垃圾回收器无法回收。
- 日志文件:定期清理或轮转旧的日志文件,防止塞满存储空间。
一个简单的内存检查习惯是,在脚本的关键节点(如循环开始前、任务完成后)输出当前内存使用情况:console.log(“内存使用: ”, runtime.memoryUsage())。观察其增长趋势。
5. 常见问题排查与脚本调试实录
即使有了“1000案例”,在实际编写和运行中,你一定会遇到各种问题。这里记录几个最典型的“坑”及其解决方案。
5.1 控件找不到(NullPointerException)
这是最常见的问题,控制台报错Cannot read property ‘click’ of null。
排查步骤:
- 确认无障碍服务已开启:脚本开头用
auto.service检查,并给出明确提示。 - 确认App已启动并进入正确页面:在
findOne()前加入sleep或waitFor,确保界面加载完成。可以先用launchApp()或startActivity()明确启动。 - 验证选择器:使用
console.log(selector.find())或console.log(selector.findOne(1000))打印找到的控件信息。更直观的方法是使用AutoJS提供的“布局范围分析”功能(悬浮窗或布局分析工具),实时查看控件信息,核对className、text、id等属性是否与代码中一致。 - 考虑动态内容或延迟加载:有些列表或内容是在滚动后才加载的。需要先滑动到对应区域,再查找控件。
- 权限问题:某些App内的控件可能需要特殊权限(如浮窗权限)才能被无障碍服务识别。
5.2 图像识别失败或坐标点击不准
排查步骤:
- 保存截图对比:在找图失败时,立即保存当前屏幕截图:
images.save(captureScreen(), “/sdcard/debug_screen.png”)。然后与你的模板图片在电脑上对比,看颜色、亮度、尺寸是否有差异。 - 调整阈值和区域:降低
threshold值,或扩大region搜索范围。 - 检查模板图:确保模板图是从当前设备的当前App版本中截取的。不同手机品牌对UI有染色,不同App版本UI会改版。
- 坐标点击的参考系:
click(x, y)的坐标是相对于屏幕左上角的绝对坐标。如果你的脚本要在不同分辨率的设备上运行,必须将坐标转换为相对比例。例如,始终点击屏幕中央:click(device.width * 0.5, device.height * 0.5)。
5.3 脚本运行不稳定,时好时坏
可能原因及对策:
- 网络波动:在网络操作前后增加重试机制和更长的等待时间。
- 系统资源紧张:手机内存不足时,App可能被后台杀死或响应缓慢。尝试关闭其他后台应用,或编写脚本时减少内存占用。
- 无障碍服务被系统回收:即“
autojs无障碍服务自动关闭”问题。除了前文提到的设置为“受保护应用”,还可以在脚本中增加“心跳”机制,定期执行一个简单的无障碍操作(如获取前台包名),让系统知道服务正在被使用,降低被回收概率。 - 随机弹窗干扰:App突然弹出的广告、通知、更新提示会打乱脚本流程。在关键操作步骤前,可以加入一个“清场”函数,尝试查找并关闭常见的弹窗元素(如
text(“跳过”).click()、className(“Button”).text(“关闭”).click())。
5.4 如何调试复杂的脚本逻辑
- 善用
console.log():在关键分支、循环开始结束、函数入口出口打印变量状态和执行进度。这是最直接的调试方式。 - 使用
try...catch定位异常:将可能出错的代码块包裹起来,在catch中打印详细的错误信息和堆栈。 - 分模块测试:不要一次性写几百行再运行。将大脚本拆分成独立的功能函数,逐个测试通过后再组装。
- 利用AutoJS的悬浮窗和工具:AutoJS Pro版本提供了更强大的调试工具,如实时查看控件信息、录制动作等,能极大提升开发效率。
构建和维护一个“1000案例”库,其意义远不止是代码的堆砌。它更像是一本由无数开发者共同撰写的“自动化生存手册”,里面记录了在各种真实、复杂的移动端环境下实现自动化的智慧、技巧和教训。对于学习者,最好的方式不是复制粘贴这一千个案例,而是精读其中几十个典型例子,理解其背后的设计模式、容错思想和优化技巧,然后结合自己的具体需求,创造出属于自己的、更优雅、更健壮的自动化解决方案。毕竟,在自动化的世界里,唯一不变的就是变化本身,而快速适应变化的能力,正是这些案例想要赋予你的核心价值。
本文还有配套的精品资源,点击获取