v8 AI Coding Examples
v8 AI Coding Examples
This page gives AI assistants practical Auto.js Pro v8 (API v1 / Rhino) templates. It is not a full API reference. It is a compact set of minimal examples that are easy to copy, adapt, and combine.
Rules:
- Target version:
v8 - UI scripts must start with
"ui";as the first executable line - Do not add
"nodejs";to v8 scripts - Use
letorvarfor variable declarations; do not useconstbecause of Rhino compatibility issues - Check permissions before using sensitive capabilities
- Do not block the UI thread with long-running work
Related docs:
1. Basic Script Template
Use this for logs, toasts, sequential tasks, and small utilities.
toast("script started");
console.log("device:", device.brand, device.model);
try {
sleep(500);
toastLog("task finished");
} catch (e) {
console.error(e);
toast("script failed: " + e);
}Useful changes:
- Put the main logic inside
tryso errors are visible - Use
console.log()/toastLog()while debugging
2. Minimal UI Template
Use this for small apps with buttons, inputs, and status text.
Warning
For v8 UI scripts, "ui"; must be the first executable line. Do not put variables, imports, or function calls before it.
"ui";
$ui.layout(
<vertical padding="16">
<text text="Auto.js Pro v8 UI example" textSize="18sp" />
<input id="name" hint="Your name" />
<button id="hello" text="Say hello" />
<text id="status" text="Waiting" />
</vertical>
);
$ui.hello.on("click", () => {
let name = String($ui.name.text() || "Auto.js Pro");
$ui.status.setText("Hello, " + name);
toast("UI updated");
});Common mistakes:
- Do not run
while (true)or longsleep()calls in click handlers - When a worker thread needs to update UI, return to the UI thread with
$ui.run(() => { ... })
3. Common UI Controls
Use this for settings pages, forms, and small control panels.
"ui";
$ui.layout(
<scroll>
<vertical padding="16">
<text text="Task settings" textSize="20sp" textStyle="bold" />
<input id="keyword" hint="Keyword" />
<checkbox id="enableLog" text="Enable logs" checked="true" />
<radiogroup id="mode">
<radio id="fast" text="Fast mode" checked="true" />
<radio id="safe" text="Safe mode" />
</radiogroup>
<spinner id="interval" entries="1s|3s|5s" />
<button id="save" text="Save" />
</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 should prefer these basic controls unless the user asks for complex lists, WebView, or custom widgets.
4. Floating Window Control Button
Use this for floating start/stop buttons, script control panels, and small overlays.
if (!floaty.checkPermission()) {
let ok = confirm(
"Floating Window Permission",
"Please grant floating window permission, then run the script again.",
);
if (!ok) {
exit();
}
floaty.requestPermission();
exit();
}
let window = floaty.window(
<frame>
<button id="action" text="Start" 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 ? "Stop" : "Start");
toast(running ? "task started" : "task stopped");
});
window.action.longClick(() => {
window.setAdjustEnabled(!window.isAdjustEnabled());
return true;
});
// Keep the script alive, otherwise the floating window closes when the script exits.
setInterval(() => {}, 1000);Notes:
floaty.requestPermission()opens the permission page; it does not wait for approval- Long-press toggles adjust mode so the window can be moved
Elegant Floating Window Permission Request in UI Mode
Use this when the script has its own UI and should guide the user to Android settings, then re-check permission when the user returns.
"ui";
function checkAndRequestFloaty() {
if (floaty.checkPermission()) {
return true;
}
$dialogs.setDefaultDialogType("app");
dialogs
.build({
title: "Floating Window Permission Required",
content:
"To show the floating control panel, find this app on the next settings page and enable \"Display over other apps\".",
positive: "Open settings",
negative: "Cancel",
cancelable: false,
})
.on("positive", function () {
floaty.requestPermission();
toast("Find this app and enable the floating window switch");
})
.on("negative", function () {
toast("Permission not granted; floating window features are unavailable");
})
.show();
return false;
}
$ui.layout(
<vertical padding="16">
<text text="Script Main UI" textSize="20sp" gravity="center" margin="20" />
<button id="start" text="Start" style="Widget.AppCompat.Button.Colored" />
</vertical>,
);
ui.emitter.on("resume", function () {
if (checkAndRequestFloaty()) {
toastLog("floating window permission is ready");
}
});
checkAndRequestFloaty();
$ui.start.click(function () {
if (checkAndRequestFloaty()) {
toast("permission granted, starting...");
}
});Notes:
- In UI mode, avoid blocking permission flows; use a dialog to guide the user
$dialogs.setDefaultDialogType("app")makes the dialog an app dialog, so it does not require floating window permission before that permission is grantedui.emitter.on("resume", ...)re-checks permission when the user returns from Android settings- If the user cancels, do not create a floating window; disable the feature or ask for permission again
5. Accessibility Automation
Use this to click widgets, fill text, and wait for screens.
function ensureAccessibility(mode) {
if (auto.service) {
auto.setMode(mode || "normal");
return;
}
let ok = confirm(
"Accessibility Permission",
"Please enable Accessibility. The script will continue after it is enabled.",
);
if (!ok) {
exit();
}
auto.waitFor();
auto.setMode(mode || "normal");
}
ensureAccessibility("fast");
function clickText(label, timeout) {
let widget = text(label).findOne(timeout || 5000);
if (!widget) {
throw new Error("text widget not found: " + label);
}
if (!widget.click()) {
let bounds = widget.bounds();
click(bounds.centerX(), bounds.centerY());
}
}
try {
clickText("Settings", 5000);
let input = className("android.widget.EditText").findOne(3000);
if (input) {
input.setText("Auto.js Pro");
}
toastLog("automation finished");
} catch (e) {
console.error(e);
toast("automation failed: " + e.message);
}Selector priority:
- Unique text:
text("Send") - Unique description:
desc("Search") - Stable id:
id("action_search") - Combined selectors:
className("android.widget.Button").text("OK")
Accessibility check recommendation:
- In normal scripts, prefer an
ensureAccessibility()wrapper and useauto.serviceto check whether the service is available - If the service is disabled, call
auto.waitFor()so the script continues after the user enables Accessibility - After the service is available, call
auto.setMode("fast")orauto.setMode("normal") - In UI mode, do not call blocking
auto.waitFor()directly; prompt the user to enable the permission and rerun, or handle it from a non-UI thread
6. Screenshot, Image Matching, and Color Matching
Use this when widgets cannot be selected reliably, such as games or custom-rendered screens.
if (!requestScreenCapture()) {
toast("failed to request screenshot permission");
exit();
}
let screen = captureScreen();
let template = images.read("/sdcard/autojs/template.png");
try {
let point = images.findImage(screen, template, {
threshold: 0.8,
});
if (point) {
toastLog("image found: " + point.x + ", " + point.y);
click(point.x, point.y);
} else {
toast("target image not found");
}
let colorPoint = images.findColor(screen, "#ff0000", {
threshold: 16,
});
if (colorPoint) {
console.log("color found:", colorPoint);
}
} finally {
screen.recycle();
template.recycle();
}Notes:
- Put templates in project assets or a stable external path
- Recycle
Imageobjects when possible to reduce memory usage - Do not loop forever when no image is found; use retry limits or timeouts
7. Java / Android API Interop
Use this to open system pages, call Android classes, and access lower-level APIs.
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());Java listener in UI:
"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);Notes:
- v8 uses Rhino and can directly access packages such as
android.*andjava.* - Less common packages can be accessed through
Packages.xxx - UI examples still must put
"ui";first
8. Files, Storage, and HTTP
Use this for saving config, reading local files, and calling APIs.
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 request failed: " + response.statusCode);
}
let data = JSON.parse(response.body.string());
console.log("origin:", data.origin);
console.log("token:", storage.get("token"));Common combinations:
- Read UI form values and save them into
storages - Load config on script startup, then run automation
- Write failed HTTP requests to a log file for debugging
9. UI + Worker Thread Task
Use this when a button starts a long-running job, background polling, HTTP requests, or file I/O that must update the UI later.
Warning
Do not run sleep(), endless loops, network requests, or heavy file I/O directly inside UI click handlers. Move heavy work into threads.start(...), then switch back to the UI thread with $ui.run(...) before updating widgets.
"ui";
$ui.layout(
<vertical padding="16">
<text text="UI + worker thread task" textSize="18sp" />
<text id="status" text="Status: waiting" />
<horizontal>
<button id="start" text="Start" />
<button id="stop" text="Stop" />
</horizontal>
</vertical>,
);
let running = false;
let worker = null;
$ui.start.on("click", function () {
if (running) {
toast("task is already running");
return;
}
running = true;
$ui.status.setText("Status: running");
worker = threads.start(function () {
try {
for (let i = 1; i <= 5 && running; i++) {
sleep(1000);
let progressText = "Status: progress " + i + "/5";
$ui.run(function () {
$ui.status.setText(progressText);
});
}
$ui.run(function () {
$ui.status.setText(running ? "Status: finished" : "Status: stopped");
});
} catch (e) {
$ui.run(function () {
$ui.status.setText("Status: error - " + e.message);
});
console.error(e);
} finally {
running = false;
}
});
});
$ui.stop.on("click", function () {
running = false;
$ui.status.setText("Status: stopping...");
});Notes:
runningis a cooperative stop flag; the worker exits on the next loop- Do not call
$ui.status.setText(...)directly from a worker thread - HTTP requests, screenshot recognition, and large file operations belong in
threads.start(...) - For complex tasks, keep business logic in functions; UI events should only start, stop, and display state
10. UI + Local Settings
Use this for settings pages, account parameters, toggle options, and restoring the previous configuration on startup.
"ui";
let storage = storages.create("ai_v8_settings_demo");
$ui.layout(
<vertical padding="16">
<text text="Local settings example" textSize="18sp" />
<input id="keyword" hint="Keyword" />
<input id="delay" inputType="number" hint="Delay in ms, for example 1000" />
<checkbox id="enableLog" text="Enable logs" />
<horizontal>
<button id="save" text="Save" />
<button id="load" text="Load" />
<button id="reset" text="Reset" />
</horizontal>
<text id="status" text="Status: waiting" />
</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("Status: config loaded");
}
function saveConfig() {
let delay = parseInt(String($ui.delay.text()), 10);
if (isNaN(delay) || delay < 0) {
toast("Delay must be a number greater than or equal to 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("Status: saved " + JSON.stringify(config));
toast("settings saved");
}
$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("Status: reset");
});
// Restore previous settings after the UI has been created.
loadConfig();Notes:
- Keep the
storages.create(name)value stable so the next run reads the same storage inputvalues are text; convert and validate numeric parameters withparseInt()/parseFloat()- Do not put real passwords or tokens in documentation examples; remind users to protect secrets in real projects
- Call
loadConfig()after the UI has been initialized so widgets exist
11. Floating Window + Accessibility Control Task
Use this when a floating button controls an automation task, for example repeatedly finding and clicking a widget.
function ensureAccessibility(mode) {
if (auto.service) {
auto.setMode(mode || "normal");
return;
}
let ok = confirm(
"Accessibility Permission",
"Please enable Accessibility. The script will continue after it is enabled.",
);
if (!ok) {
exit();
}
auto.waitFor();
auto.setMode(mode || "normal");
}
ensureAccessibility("fast");
if (!floaty.checkPermission()) {
let ok = confirm(
"Floating Window Permission",
"Please grant floating window permission, then run the script again.",
);
if (!ok) {
exit();
}
floaty.requestPermission();
exit();
}
let running = false;
let worker = null;
let window = floaty.window(
<vertical padding="8" bg="#ddffffff">
<text id="status" text="Status: stopped" textColor="#333333" />
<horizontal>
<button id="action" text="Start" w="70" h="40" />
<button id="close" text="Close" w="70" h="40" />
</horizontal>
</vertical>,
);
window.setPosition(100, 300);
window.exitOnClose();
function setFloatyStatus(text) {
ui.run(function () {
window.status.setText(text);
window.action.setText(running ? "Stop" : "Start");
});
}
function clickTargetOnce() {
let target = text("OK").findOne(1000);
if (!target) {
return false;
}
if (!target.click()) {
let bounds = target.bounds();
click(bounds.centerX(), bounds.centerY());
}
return true;
}
function startTask() {
if (running) {
toast("task is already running");
return;
}
running = true;
setFloatyStatus("Status: running");
worker = threads.start(function () {
try {
while (running) {
let clicked = clickTargetOnce();
if (clicked) {
toastLog("target widget clicked");
sleep(800);
} else {
sleep(500);
}
}
} catch (e) {
console.error(e);
toast("automation task failed: " + e.message);
} finally {
running = false;
setFloatyStatus("Status: stopped");
}
});
}
function stopTask() {
running = false;
setFloatyStatus("Status: stopping...");
}
window.action.click(function () {
if (running) {
stopTask();
} else {
startTask();
}
});
window.action.longClick(function () {
window.setAdjustEnabled(!window.isAdjustEnabled());
return true;
});
window.close.click(function () {
running = false;
window.close();
exit();
});
setInterval(function () {}, 1000);Notes:
ensureAccessibility("fast")checksauto.service; if disabled, it waits until the user enables Accessibility and then continues- Closing the floating window exits the script to avoid leaving background work behind
runningis the stop flag; the worker exits on the next loop- In real projects, replace
text("OK")with a stable selector from the target app, such asid(...),desc(...), or combined conditions - Long-press the start/stop button to toggle adjust mode and move the floating window
Prompt for AI Assistants
Use this prompt to reduce version confusion:
Generate code for Auto.js Pro v8 (API v1 / Rhino).
If it is a UI script, the first executable line must be "ui";.
Do not use v9 / Node.js require, async APIs, or "nodejs";.
Use let or var for variable declarations. Do not use const.
Check or request permissions before using accessibility, floating windows, or screenshots.
Prefer minimal runnable code and explain which values should be changed.