v8 AI 编码示例
2026/4/25大约 7 分钟
v8 AI 编码示例
本页用于给 AI 助手提供 Auto.js Pro v8(第一代 API / Rhino) 的常用代码模板。它不是完整 API 文档,而是一组更适合复制、改写和组合的最小示例。
使用规则:
- 默认版本:
v8 - UI 脚本第一行必须是
"ui"; - 普通脚本不要写
"nodejs"; - 变量声明使用
let或var,不要使用const(Rhino 兼容问题) - 需要权限的示例要先检查权限,再执行动作
- 长耗时任务不要阻塞 UI 线程
相关文档:
1. 普通脚本基础模板
适合:日志、提示、顺序执行、简单任务。
toast("脚本开始");
console.log("device:", device.brand, device.model);
try {
sleep(500);
toastLog("任务完成");
} catch (e) {
console.error(e);
toast("脚本出错: " + e);
}常见修改点:
- 把核心逻辑放到
try中,方便定位错误 - 需要调试时优先用
console.log()/toastLog()
2. UI 最小模板
适合:带按钮、输入框、状态文本的小工具。
注意
只要使用 v8 UI,"ui"; 必须是脚本第一行,前面不能有变量声明、导入或注释外的可执行代码。
"ui";
$ui.layout(
<vertical padding="16">
<text text="Auto.js Pro v8 UI 示例" textSize="18sp" />
<input id="name" hint="请输入名字" />
<button id="hello" text="打招呼" />
<text id="status" text="等待操作" />
</vertical>,
);
$ui.hello.on("click", () => {
let name = String($ui.name.text() || "Auto.js Pro");
$ui.status.setText("Hello, " + name);
toast("已更新界面");
});常见错误:
- 不要在点击事件中直接写
while (true)或长时间sleep() - 子线程更新 UI 时需要回到 UI 线程,例如
$ui.run(() => { ... })
3. 常用 UI 控件组合
适合:设置页、表单、小型工具面板。
"ui";
$ui.layout(
<scroll>
<vertical padding="16">
<text text="任务设置" textSize="20sp" textStyle="bold" />
<input id="keyword" hint="关键字" />
<checkbox id="enableLog" text="启用日志" checked="true" />
<radiogroup id="mode">
<radio id="fast" text="快速模式" checked="true" />
<radio id="safe" text="稳定模式" />
</radiogroup>
<spinner id="interval" entries="1秒|3秒|5秒" />
<button id="save" text="保存配置" />
</vertical>
</scroll>,
);
$ui.save.on("click", () => {
let config = {
keyword: String($ui.keyword.text()),
enableLog: $ui.enableLog.checked,
mode: $ui.fast.checked ? "fast" : "safe",
intervalIndex: $ui.interval.getSelectedItemPosition(),
};
toastLog(JSON.stringify(config));
});AI 生成 UI 时应优先选择这些基础控件,除非用户明确要求复杂列表、WebView 或自定义控件。
4. 悬浮窗控制按钮
适合:悬浮启动/停止按钮、脚本控制面板、辅助工具入口。
if (!floaty.checkPermission()) {
let ok = confirm("悬浮窗权限", "请先授予悬浮窗权限,然后重新运行脚本");
if (!ok) {
exit();
}
floaty.requestPermission();
exit();
}
let window = floaty.window(
<frame>
<button id="action" text="开始" w="90" h="40" bg="#77ffffff" />
</frame>,
);
window.setPosition(100, 300);
window.exitOnClose();
let running = false;
window.action.click(() => {
running = !running;
window.action.setText(running ? "停止" : "开始");
toast(running ? "任务已开始" : "任务已停止");
});
window.action.longClick(() => {
window.setAdjustEnabled(!window.isAdjustEnabled());
return true;
});
// 保持脚本运行,否则悬浮窗会随脚本结束而关闭。
setInterval(() => {}, 1000);注意事项:
floaty.requestPermission()只会跳转到授权页面,不会阻塞等待授权结果- 长按按钮切换调整模式,便于移动悬浮窗
UI 模式下优雅申请悬浮窗权限
适合:脚本本身有主界面,需要引导用户去系统设置页打开悬浮窗权限,并在用户返回时自动复查状态。
"ui";
function checkAndRequestFloaty() {
if (floaty.checkPermission()) {
return true;
}
$dialogs.setDefaultDialogType("app");
dialogs
.build({
title: "需要悬浮窗权限",
content:
"为了显示悬浮控制台,请在随后的设置页中找到本应用并开启“允许显示在其他应用上”。",
positive: "去开启",
negative: "取消",
cancelable: false,
})
.on("positive", function () {
floaty.requestPermission();
toast("请找到本应用并开启悬浮窗开关");
})
.on("negative", function () {
toast("未授予权限,悬浮窗功能不可用");
})
.show();
return false;
}
$ui.layout(
<vertical padding="16">
<text text="脚本主界面" textSize="20sp" gravity="center" margin="20" />
<button
id="start"
text="开始运行"
style="Widget.AppCompat.Button.Colored"
/>
</vertical>,
);
ui.emitter.on("resume", function () {
if (checkAndRequestFloaty()) {
toastLog("悬浮窗权限已就绪");
}
});
checkAndRequestFloaty();
$ui.start.click(function () {
if (checkAndRequestFloaty()) {
toast("权限已开启,正在启动...");
}
});说明:
- UI 模式下不要用阻塞式等待权限的写法,应使用对话框引导用户操作
$dialogs.setDefaultDialogType("app")让对话框以应用内对话框显示,避免还没拿到悬浮窗权限时对话框也依赖悬浮窗ui.emitter.on("resume", ...)用于监听用户从设置页返回,再次检查权限- 用户取消时不要强制继续创建悬浮窗,应禁用相关功能或提示重新授权
5. Java / Android API 调用
适合:打开系统页面、调用 Android 类、实现更底层能力。
importClass(android.content.Intent);
importClass(android.provider.Settings);
importClass(android.net.Uri);
let intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.parse("package:" + context.getPackageName()));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
let builder = new java.lang.StringBuilder();
builder.append("package=");
builder.append(context.getPackageName());
console.log(builder.toString());UI 中实现 Java 点击监听:
"ui";
$ui.layout(
<vertical padding="16">
<button id="btn" text="Java Listener" />
</vertical>,
);
let listener = new android.view.View.OnClickListener(function (view) {
toast("clicked by Java listener");
});
$ui.btn.setOnClickListener(listener);注意事项:
- v8 使用 Rhino,可直接访问
android.*、java.*等包 - 非常见包可通过
Packages.xxx访问 - UI 示例仍必须把
"ui";放在第一行
6. 文件、存储与 HTTP
适合:保存配置、读取本地文件、调用接口。
let storage = storages.create("demo_config");
storage.put("token", "example-token");
storage.put("enabled", true);
let dir = "/sdcard/autojs";
let file = files.join(dir, "log.txt");
files.ensureDir(dir);
files.append(file, new Date().toISOString() + " script started\n");
let response = http.get("https://httpbin.autojs.run/get");
if (response.statusCode !== 200) {
throw new Error("HTTP 请求失败: " + response.statusCode);
}
let data = JSON.parse(response.body.string());
console.log("origin:", data.origin);
console.log("token:", storage.get("token"));常见组合:
- UI 表单读取用户输入后写入
storages - 脚本启动时读取配置,再执行自动化任务
- HTTP 请求失败时写入日志,方便排查
7. UI + 子线程任务
适合:按钮启动耗时任务、后台轮询、执行 HTTP / 文件读写后更新界面。
注意
不要在 UI 点击事件中直接执行 sleep()、死循环、网络请求或大量文件读写。耗时任务放到 threads.start(...),更新界面时再用 $ui.run(...) 回到 UI 线程。
"ui";
$ui.layout(
<vertical padding="16">
<text text="UI + 子线程任务" textSize="18sp" />
<text id="status" text="状态:等待开始" />
<horizontal>
<button id="start" text="开始任务" />
<button id="stop" text="停止任务" />
</horizontal>
</vertical>,
);
let running = false;
let worker = null;
$ui.start.on("click", function () {
if (running) {
toast("任务正在运行");
return;
}
running = true;
$ui.status.setText("状态:运行中");
worker = threads.start(function () {
try {
for (let i = 1; i <= 5 && running; i++) {
sleep(1000);
let progressText = "状态:进度 " + i + "/5";
$ui.run(function () {
$ui.status.setText(progressText);
});
}
$ui.run(function () {
$ui.status.setText(running ? "状态:任务完成" : "状态:已停止");
});
} catch (e) {
$ui.run(function () {
$ui.status.setText("状态:出错 - " + e.message);
});
console.error(e);
} finally {
running = false;
}
});
});
$ui.stop.on("click", function () {
running = false;
$ui.status.setText("状态:正在停止...");
});注意事项:
running用于协作停止,让子线程在下一轮循环时退出- 不要直接从子线程调用
$ui.status.setText(...) - 网络请求、截图识别、大文件读写都适合放进
threads.start(...) - 如果任务很复杂,应把核心逻辑封装成函数,UI 事件只负责启动、停止和显示状态
8. UI + 本地配置
适合:设置页、账号参数、开关选项、脚本启动时恢复上次配置。
"ui";
let storage = storages.create("ai_v8_settings_demo");
$ui.layout(
<vertical padding="16">
<text text="本地配置示例" textSize="18sp" />
<input id="keyword" hint="关键字" />
<input id="delay" inputType="number" hint="延迟毫秒,例如 1000" />
<checkbox id="enableLog" text="启用日志" />
<horizontal>
<button id="save" text="保存" />
<button id="load" text="读取" />
<button id="reset" text="重置" />
</horizontal>
<text id="status" text="状态:等待操作" />
</vertical>,
);
function loadConfig() {
let keyword = storage.get("keyword", "");
let delay = storage.get("delay", 1000);
let enableLog = storage.get("enableLog", true);
$ui.keyword.setText(String(keyword));
$ui.delay.setText(String(delay));
$ui.enableLog.checked = !!enableLog;
$ui.status.setText("状态:配置已读取");
}
function saveConfig() {
let delay = parseInt(String($ui.delay.text()), 10);
if (isNaN(delay) || delay < 0) {
toast("延迟必须是大于等于 0 的数字");
return;
}
let config = {
keyword: String($ui.keyword.text()),
delay: delay,
enableLog: $ui.enableLog.checked,
};
storage.put("keyword", config.keyword);
storage.put("delay", config.delay);
storage.put("enableLog", config.enableLog);
$ui.status.setText("状态:已保存 " + JSON.stringify(config));
toast("配置已保存");
}
$ui.save.on("click", saveConfig);
$ui.load.on("click", loadConfig);
$ui.reset.on("click", function () {
storage.clear();
$ui.keyword.setText("");
$ui.delay.setText("1000");
$ui.enableLog.checked = true;
$ui.status.setText("状态:已重置");
});
// 启动时自动恢复上次配置。
loadConfig();注意事项:
storages.create(name)的name应固定,方便下次启动读取同一份配置input读取到的是文本,数字参数要用parseInt()/parseFloat()转换并校验- 不要把密码、Token 等敏感信息明文写进文档示例;真实项目应提醒用户自行保护
- UI 初始化完成后再调用
loadConfig(),确保控件已经存在
给 AI 的固定提示词
可以把下面这段贴给 AI,减少版本混淆:
请使用 Auto.js Pro v8(第一代 API / Rhino)生成代码。
如果是 UI 脚本,第一行必须是 "ui";。
不要使用 v9 / Node.js 的 require、async API 或 "nodejs";。
变量声明请使用 let 或 var,不要使用 const。
需要权限的能力(无障碍、悬浮窗、截图)必须先检查或请求权限。
请优先给出最小可运行代码,并说明需要修改的参数。