自动化脚本 API
device.* / inspector / app 全量方法参数参考,含 Android/iOS 平台差异
脚本运行时三个全局对象自动注入:device、inspector、app,以及 vars 共享变量表。所有 device.* 方法均为 async,必须 await。
平台标记:[跨平台] = Android + iOS 均支持,[Android] = 仅 Android(redroid/真机),[iOS] = 仅 iOS(WDA)。
| 方法 | 签名 | 平台 | 说明 |
|---|
device.tap | (x, y) | 跨平台 | 点击坐标点 |
device.doubleTap | (x, y) | 跨平台 | 双击坐标点 |
device.longPress | (x, y, seconds?) | 跨平台 | 长按,seconds 默认 1.0 |
device.swipe | (fromX, fromY, toX, toY, seconds?) | 跨平台 | 滑动,seconds 默认 0.3 |
device.drag | (fromX, fromY, toX, toY, duration?) | 跨平台 | 拖拽(先长按再移),duration 默认 1.0 |
device.pinch | (scale, velocity?) | 跨平台 | 双指缩放,scale>1 放大,<1 缩小 |
await device.tap(540, 960)
await device.swipe(540, 1400, 540, 400, 0.4) // 向上翻页
await device.drag(200, 600, 600, 600, 1.2) // 拖拽
await device.pinch(2.0) // 放大 2×
| 方法 | 签名 | 平台 | 说明 |
|---|
device.inputText | (text) | 跨平台 | 向聚焦输入框输入文本 |
device.clearText | (locator) | 跨平台 | 清空 locator 匹配的输入框 |
device.pressKey | (key) | Android | 发送按键事件("Enter" / "Back" / "Tab" 等) |
await device.tapElement({ strategy: "label", value: "用户名" })
await device.inputText("admin")
await device.pressKey("Enter") // Android only
| 方法 | 签名 | 平台 | 说明 |
|---|
device.launchApp | (pkg) | 跨平台 | 按包名/bundle ID 启动 App |
device.terminateApp | (pkg) | 跨平台 | 强制停止 App |
device.openUrl | (url) | 跨平台 | 浏览器/URL Scheme 打开链接 |
await device.launchApp("com.example.app")
await device.openUrl("https://example.com")
await device.terminateApp("com.example.app")
| 方法 | 签名 | 平台 | 说明 |
|---|
device.home | () | 跨平台 | 返回桌面 |
device.back | () | Android | 返回键 |
device.power | (action) | Android | 电源操作:"screen_on" / "screen_off" / "keyevent_power" |
device.screenSize | () | 跨平台 | 返回 { width, height } 屏幕分辨率 |
device.info | () | 跨平台 | 设备信息(platform / model / os_version 等) |
| 方法 | 签名 | 平台 | 说明 |
|---|
device.getClipboard | () | 跨平台 | 读取剪贴板文本 |
device.setClipboard | (text) | 跨平台 | 写入剪贴板 |
| 方法 | 签名 | 平台 | 说明 |
|---|
device.find | (locator) | 跨平台 | 查找一个元素,不存在抛出异常(用作检查点) |
device.findAll | (locator) | 跨平台 | 查找所有匹配,不存在返回 [] |
device.tapElement | (locator) | 跨平台 | 查找并点击元素中心 |
device.exists | (locator) | 跨平台 | 检测元素是否存在(不抛异常) |
device.waitFor | (locator, timeoutSecs?) | 跨平台 | 等待元素出现,默认超时 10 秒 |
// 存在性检测
if (await device.exists({ strategy: "text", value: "跳过" })) {
await device.tapElement({ strategy: "text", value: "跳过" })
}
// 等待页面跳转完成
await device.waitFor({ strategy: "resource_id", value: "com.app:id/home_tab" }, 15)
| 方法 | 签名 | 平台 | 说明 |
|---|
device.scroll | (direction, fraction?, duration?) | 跨平台 | 方向滚动,fraction 为屏幕比例(0~1),默认 0.5 |
device.scrollToElement | (locator, direction?, maxSwipes?) | 跨平台 | 反复滚动直到找到元素 |
await device.scroll("down", 0.6, 0.4)
// 滚动到目标元素
await device.scrollToElement(
{ strategy: "text", value: "加载更多" },
"down",
15
)
| 方法 | 签名 | 平台 | 说明 |
|---|
device.uiSnapshot | () | 跨平台 | 捕获 UI 树快照,返回 { snapshotId } |
device.nodeParent | (snapshotId, path) | 跨平台 | 获取父节点 |
device.nodeChildren | (snapshotId, path) | 跨平台 | 获取子节点列表 |
device.nodeSiblings | (snapshotId, path) | 跨平台 | 获取兄弟节点列表 |
device.selectNodes | (snapshotId, select) | 跨平台 | CSS 风格选择器批量筛选节点 |
| 方法 | 签名 | 平台 | 说明 |
|---|
device.screenshot | () | 跨平台 | 返回 base64 PNG 截图 |
以下方法仅 Android 支持,需节点开启 vision feature。
| 方法 | 签名 | 说明 |
|---|
device.ocr | () | OCR 识别屏幕所有文字块,返回 [{ text, rect, confidence? }] |
device.findText | (text) | OCR 查找包含文字的区域,返回第一个匹配或 null |
device.tapText | (text) | OCR 查找并点击文字区域,未找到抛出异常 |
// Android only
await device.tapText("立即登录")
const r = await device.findText("验证码")
if (r) await device.tap(r.rect.x + r.rect.width / 2, r.rect.y + r.rect.height / 2)
以下方法仅 Android 支持,需节点编译时启用 --features frida 且镜像内置 frida-server-hidden。iOS 暂不支持。
统一 Frida 入口,支持 session 复用与自动重建。
| 参数 | 类型 | 说明 |
|---|
slot | string | Session 复用 key(同 key 复用同一 session) |
src | string | null | JS 脚本源码 或 @脚本名;null = 复用现有 session |
pkg | string | {spawn:string} | null | attach 包名;{spawn:"com.x"} = spawn-gate;null = 复用 |
method | string | null | 调用 rpc.exports 方法名;null = 仅 attach |
args | unknown | null | 传给 method 的参数 |
const HOOK = `
rpc.exports = {
init() { Java.perform(() => { /* hook */ }) },
getModel() { return Java.use("android.os.Build").MODEL.value }
}
`
// 首次调用:attach + call init
await device.frida("h", HOOK, "com.target", "init", null)
// 复用 session 调用另一方法
const model = await device.frida("h", null, null, "getModel", null)
// spawn-gate(挂起启动,注入后 resume)
await device.frida("gate", HOOK, { spawn: "com.target" }, "init", null)
// 脚本仓库引用(~/.aixauto/frida-scripts/ssl-unpin.js)
await device.frida("ssl", "@ssl-unpin", "com.target", "enable", null)
// 内置指纹 spoof(sentinel)
await device.frida("spoof", "@aixauto-spoof", { spawn: "com.target" }, null, null)
订阅 Frida send() 事件流,收集到 .stop() 为止。
| 参数 | 说明 |
|---|
slot / src / pkg | 同 device.frida |
eventName | 事件类型过滤(匹配 send({ type: eventName, ... })) |
返回 { stop(): Promise<unknown[]> }。
const col = device.frida.collect("tls", TLS_HOOK, "com.target", "cert")
await device.launchApp("com.target")
await new Promise(r => setTimeout(r, 5000))
const certs = await col.stop()
// [{ host: "api.target.com", cert: "MIIB..." }, ...]
执行 W3C Actions 协议序列,支持多指精确时序(跨平台)。
await device.performActions([
{
type: "pointer", id: "finger1",
actions: [
{ type: "pointerMove", x: 400, y: 800 },
{ type: "pointerDown", button: 0 },
{ type: "pointerMove", x: 200, y: 600, duration: 500 },
{ type: "pointerUp", button: 0 },
]
}
])
| 全局 | 说明 |
|---|
inspector.dump() | 实时 UI 树(嵌套对象),适合脚本内遍历 |
app.list() | 已安装 App 列表 [{ package, label }] |
vars | 运行时注入的变量(来自脚本配置 + 调用时覆盖) |
const tree = await inspector.dump()
const apps = await app.list()
const username = vars.username ?? "guest"
所有元素方法接受 { strategy, value } 定位器。
| strategy | 平台 | 说明 |
|---|
text | Android | 可见文字精确匹配 |
text_contains | Android | 可见文字子串 |
resource_id | Android | com.app:id/view_id |
content_desc | Android | contentDescription |
class_name | 跨平台 | 控件类型 |
label | iOS/跨平台 | accessibilityIdentifier / contentDescription |
x_path | 跨平台 | XPath(注意拼写 x_path,非 xpath) |
predicate | iOS | NSPredicate 字符串 |
automation_id | Windows | UIA AutomationId |
control_type | Windows | UIA ControlType |
role | macOS | AX role |
优先使用稳定 ID(resource_id / label / automation_id),其次 text,x_path 最后手段。
| 方法 | Android | iOS |
|---|
| tap / doubleTap / longPress / swipe / drag / pinch | ✓ | ✓ |
| inputText / clearText | ✓ | ✓ |
| launchApp / terminateApp / openUrl / home | ✓ | ✓ |
| find / findAll / tapElement / exists / waitFor | ✓ | ✓ |
| scroll / scrollToElement | ✓ | ✓ |
| uiSnapshot / selectNodes | ✓ | ✓ |
| screenshot / screenSize / info | ✓ | ✓ |
| getClipboard / setClipboard / performActions | ✓ | ✓ |
| back | ✓ | ✗ |
| pressKey / power | ✓ | ✗ |
| ocr / findText / tapText | ✓ | ✗ |
| device.frida / device.frida.collect | ✓ | ✗ |