Tasker JavaScriptlet 详解 嵌入 JavaScript 让 Tasker 获得完整编程能力
JavaScriptlet 是什么
JavaScriptlet 是 Tasker 中嵌入的 JavaScript 执行环境。你写的 JS 代码在 Tasker 内部的小型 JS 引擎里运行,与 Tasker 的变量、Profile、Task 等核心组件完全打通。
一句话理解:JavaScriptlet 让你不用写纯 Tasker Action 逻辑,而是用更灵活的 JS 语法来控制 Tasker 的自动化流程。
为什么选 JavaScriptlet 而不是纯 Action
纯 Tasker Action 虽然覆盖了 190+ 场景,但以下事情纯 Action 很难做到:
| 需求 | 纯 Action 做法 | JavaScriptlet 做法 |
|---|---|---|
| 复杂 JSON 解析 | 用 Read JSON 逐个字段映射 | JSON.parse(data) 一行搞定 |
| 数组/列表遍历 | For 循环(但 For 不支持动态长度) | array.forEach(item => ...) |
| 正则提取 | Read JSON 间接实现 | str.match(/pattern/) |
| 数学计算 | Variable Math 支持基础运算 | Math.sqrt(x) / Math.round() / Math.floor() |
| 条件赋值 | If/Else + Variable Set | var x = cond ? a : b |
| 错误处理 | 只能看日志 | try { ... } catch(e) { ... } |
Tasker API 参考
JavaScriptlet 通过 tasker 对象访问所有 Tasker 功能。以下是最常用的 API:
变量操作
// 读取全局变量(如果变量不存在返回空字符串)
var battery = tasker.getGlobal("%BATT");
// 设置全局变量
tasker.setGlobal("%Doubled", battery * 2);
// 读取局部变量(仅当前 Task 内有效)
var tmp = tasker.getLocal("%tmp");
// 设置局部变量
tasker.setLocal("%inner", "临时值");
Task / Profile 操作
// 检查 Task 是否存在
if (tasker.taskExists("MyTask")) { ... }
// 执行另一个 Task(priority 1-10,越高越优先)
tasker.runTask("CleanTempFiles", 5);
// 启用/禁用 Profile
tasker.enableProfile("NightMode", false); // 禁用
tasker.enableProfile("NightMode", true); // 启用
// 终止当前 Task
tasker.stop();
UI 与通知
// 创建系统通知
tasker.notify("标题", "内容文本", "notification_icon");
// 弹窗(会阻塞 Task 直到用户关闭)
tasker.popup("提示内容", "标题");
// 朗读(TTS)
tasker.say("当前电量" + battery + " %");
返回值
// 给 Tasker 主流程返回一个值
// 可以在 Tasker 里用 JSLET 变量读取
tasker.returnValue("处理完成");
// 或返回对象 / 数字
tasker.returnValue({ success: true, count: 42 });
实战示例
示例一:解析 API 返回的复杂 JSON
// HTTP Request 把 API 响应存在 %HTTPD 里
var raw = tasker.getGlobal("%HTTPD");
var data = JSON.parse(raw);
// 提取嵌套字段
var city = data.results[0].address_components.find(c =>
c.types.includes("locality")
).long_name;
var lat = data.results[0].geometry.location.lat;
tasker.setGlobal("%CityName", city);
tasker.setGlobal("%Latitude", lat);
示例二:批量处理变量列表
// 假设 %Items = "苹果,橘子,香蕉"(逗号分隔)
var raw = tasker.getGlobal("%Items");
var items = raw.split(",");
// 过滤掉空项、去重、排序
var uniqueSorted = [...new Set(items.filter(i => i.trim()))].sort();
tasker.setGlobal("%ProcessedList", uniqueSorted.join(","));
tasker.setGlobal("%ItemCount", uniqueSorted.length);
示例三:智能省电判断
var battery = parseFloat(tasker.getGlobal("%BATT"));
var charging = tasker.getGlobal("%CHARGING"); // "1" 表示在充电
var screenOn = tasker.getGlobal("%SCREEN"); // "true" 表示亮屏
var shouldSave = false;
var reason = "";
if (battery < 15 && charging !== "1") {
shouldSave = true;
reason = "低电量未充电";
} else if (screenOn === "false" && battery < 50) {
shouldSave = true;
reason = "屏幕关闭但电量一般";
}
tasker.setGlobal("%ShouldSave", shouldSave ? "1" : "0");
tasker.setGlobal("%SaveReason", reason);
JavaScriptlet 与纯 JS 的差异
JavaScriptlet 不是标准浏览器 JS:
没有的能力:
- ❌ DOM(没有 HTML 文档)
- ❌
fetch()/XMLHttpRequest(网络请求用 Tasker 的 HTTP Request Action) - ❌
console.log()(调试用 Popup 或 Notify 输出) - ❌
setTimeout/setInterval(Tasker 是单线程同步执行的) - ❌ 第三方库(lodash、moment 等不能引入)
额外有的能力(Tasker 扩展):
- ✅
tasker.*API(Tasker 专属) - ✅
tasker.returnValue()(把结果传回 Tasker 主流程)
调试技巧
JavaScriptlet 没有调试器,但有几个实用方法:
1. 用 Popup 输出中间值
tasker.popup("中间变量 x = " + x, "调试");
→ 执行到这会弹窗暂停,确认后继续。开发时加,上线前删。
2. 用 Notify 异步输出
tasker.notify("JS Debug", "array 长度:" + array.length);
→ 不阻塞 Task 执行,在通知栏看。
3. 分步执行把复杂 JS 拆成多个小的 JavaScriptlet Action,逐步验证:
- 第一步:读取变量 + Popup 确认值正确
- 第二步:处理数据 + Popup 确认处理正确
- 第三步:写入变量
4. 异常捕获
try {
// 可能出错的代码
JSON.parse(tasker.getGlobal("%HTTPD"));
} catch(e) {
tasker.notify("JS 错误", e.message);
tasker.returnValue("error");
}
最佳实践
- 优先读写局部变量
tasker.getLocal/setLocal——不污染全局空间,Task 结束自动销毁 - 代码要短——单段 JS 建议控制在 20-50 行,太长就拆成多个 Action
- 注释要写清楚——Tasker 里代码不能高亮,注释是唯一文档
- 处理所有异常——
try-catch包住可能出错的地方,不要让 JS 静默失败 - 不要替代纯 Action——简单的
Variable Set不如直接用 Action,JS 用在 Action 做不到的地方