Auto.js进阶指南:从启动应用到精准操控——Activity启动与Shell命令实战解析

张开发
2026/4/17 10:10:21 15 分钟阅读

分享文章

Auto.js进阶指南:从启动应用到精准操控——Activity启动与Shell命令实战解析
1. Auto.js应用启动基础与Activity概念解析如果你用过Auto.js的app.launch()函数可能会觉得打开应用很简单。但实际开发中我们经常需要直接跳转到应用内的某个特定页面比如微信的发现页、支付宝的转账界面这时候就需要理解Android的Activity机制。我刚开始接触时经常混淆应用包名和Activity名称直到踩过几次坑才明白它们的区别。应用包名PackageName就像人的身份证号每个应用都有唯一标识。比如微信永远是com.tencent.mm支付宝永远是com.eg.android.Alipaygphone。而Activity则是应用内部的不同功能页面相当于人的不同身份——同一个人可以是父亲、丈夫、员工等多个角色。以微信为例com.tencent.mm.ui.LauncherUI主界面com.tencent.mm.plugin.subapp.ui.friend.FMessageConversationUI朋友圈com.tencent.mm.plugin.wallet.pay.ui.WalletPayUI支付页面获取这些信息最直接的方式是使用Auto.js的布局分析功能。打开目标页面后运行以下代码console.log(当前包名: currentPackage()); console.log(当前Activity: currentActivity());2. 两种核心跳转方式对比startActivity vs Shell命令2.1 app.startActivity的实战技巧startActivity方法最接近原生Android开发的方式它通过构造Intent对象实现精准跳转。我在电商App自动化项目中发现这种方法特别适合需要传递复杂参数的场景。比如要跳转到微信的指定聊天窗口app.startActivity({ packageName: com.tencent.mm, className: com.tencent.mm.ui.chatting.ChattingUI, extras: { Chat_User: wxid_123456789, // 对方微信号 key_need_send_video: false } });关键参数获取有几种实用方法使用Android SDK的adb命令adb shell dumpsys activity top第三方工具如Activity Launcher可以查看所有暴露的Activity反编译APK查看AndroidManifest.xml需一定技术基础2.2 Shell命令的极简之道当startActivity遇到复杂参数束手无策时Shell命令往往能出奇制胜。特别是处理那些非标准Intent的场景比如我遇到过某银行App的指纹登录页面只有用am命令才能直接唤醒shell(am start -n com.bank.android/.biometric.BiometricLoginActivity --es verify_type fingerprint, true);am命令的-n参数直接指定组件名避免了Intent的自动补全问题。这里分享一个实用技巧把常用命令封装成函数function startActivity(pkg, activity, extras{}){ let cmd am start -n ${pkg}/${activity}; Object.keys(extras).forEach(k { if(typeof extras[k] string) cmd --es ${k} ${extras[k]}; else if(typeof extras[k] boolean) cmd --ez ${k} ${extras[k]}; }); return shell(cmd, true); }3. 高阶实战复杂工作流构建3.1 跨应用协作的三种模式在实际自动化流程中经常需要多个应用配合。比如截图→OCR识别→填写表单的流程。这时可以组合使用不同方法接力模式前一个Activity结束后自动启动下一个app.startActivity({ packageName: com.android.camera, className: com.android.camera.Camera }); waitForActivity(com.android.camera.Camera); // 拍照完成后... shell(am start -a android.intent.action.VIEW -d file:///sdcard/photo.jpg -t image/*);并行模式使用线程同时执行多个操作threads.start(function(){ shell(pm enable com.tencent.mm); // 启用微信 }); app.launch(com.alipay.mobile); // 同时启动支付宝条件触发基于界面状态决定下一步while(!textContains(确认支付).exists()){ if(text(重新加载).exists()) click(重新加载); sleep(1000); }3.2 系统级命令的深度整合Auto.js的Shell功能可以调用所有Android系统命令这打开了无限可能。比如我在自动化测试中常用的组合技// 清空应用数据后重新初始化 shell(pm clear com.example.app, true); // 调整系统设置 shell(settings put system screen_brightness 150, true); // 启动应用并等待主界面 app.launch(com.example.app); waitForActivity(com.example.app.MainActivity); // 截图验证 shell(screencap -p /sdcard/verify.png, true);特别提醒使用root权限时要注意安全建议用try-catch处理异常try { shell(pm disable com.android.bluetooth, true); } catch(e) { toast(禁用蓝牙失败: e); }4. 避坑指南与性能优化4.1 常见问题排查清单权限问题确保已授予Auto.js必要的权限if(!requestShellPermission()){ alert(请授予Shell权限); exit(); }ActivityNotFound异常检查是否拼写错误或需要先启动父Activity跨版本兼容不同Android版本对Intent的限制不同建议测试时添加版本判断if(device.sdkInt 30) { // Android 11的特殊处理 }4.2 让脚本飞起来的技巧经过大量实测我总结出几个性能要点减少Shell进程创建连续执行多条命令时使用Shell对象比多次调用shell()快3-5倍let sh new Shell(true); sh.exec(am start -n com.example/.Activity1); sh.exec(input tap 500 500); sh.exit(); // 必须手动退出预加载常用应用在脚本开头预先加载可能用到的包const APP_CACHE { wechat: {pkg: com.tencent.mm, main: com.tencent.mm.ui.LauncherUI}, alipay: {pkg: com.eg.android.Alipaygphone, main: com.alipay.mobile.quinox.LauncherActivity} };智能等待策略混合使用多种等待条件function smartWait(activity, timeout10000){ let start Date.now(); while(Date.now() - start timeout) { if(currentActivity() activity) return true; if(desc(关闭).exists()) click(desc(关闭)); sleep(500); } return false; }5. 企业级实战案例解析去年为某物流公司开发自动化巡检系统时我们遇到了这样的需求每天定时检查20多个App的特定页面记录加载时间并截图存档。最终方案结合了多种技术const APPS [ {name: ERP系统, pkg: com.example.erp, activity: .MainActivity}, // ...其他应用配置 ]; function checkAllApps(){ APPS.forEach(app { let startTime Date.now(); // 冷启动测试 shell(am force-stop ${app.pkg}, true); app.startActivity({ packageName: app.pkg, className: app.activity, flags: [activity_new_task] }); // 智能等待 if(!waitForPackage(app.pkg, 5000)){ log(${app.name}启动超时); return; } // 性能记录 let loadTime Date.now() - startTime; shell(screencap -p /sdcard/${app.pkg}_${Date.now()}.png, true); log(${app.name}加载耗时: ${loadTime}ms); // 返回桌面 home(); }); }这个案例的关键在于正确处理应用的生命周期。我们发现有些App会在后台自动重启导致检测结果不准确。最终通过am force-stop确保每次都是冷启动测试使数据具有可比性。

更多文章