Tasker 变量调试技巧 检查变量值 监视变化 处理空值与类型
变量调试的常见问题
变量问题可能表现为:
- Profile 不触发(因为 Variable Value Context 条件不满足)
- Tasker Action 显示错误(变量值不符合预期)
- If/Else 条件永远走同一个分支(条件里的变量不对)
- 变量值在应该变化的时候没变
- 空字符串被当成正常值处理
查看变量值的四种方法
方法一:变量列表界面
Tasker 主界面 → 变量 Tab
这里会列出所有已知的全局用户变量。点击变量可以查看当前值、编辑值。
限制:
- 不显示系统变量(%BATT、%TIME 等)
- 不显示局部变量(%myvar 全小写)
- 刷新不够实时(点其他 Tab 再切回来才更新)
方法二:运行日志
Tasker 菜单 → 数据 → 运行日志
把日志级别调到详细,变量读写操作都会记录:
[Variable] Set global %AutoProfile to 1
[Variable] Read %BATT = 78
[Variable] Set local %result to "success"
日志是实时的,最适合调试。
方法三:Popup / Notify 输出
在 Task 里临时加调试 Action:
Action 1:Popup → "调试:%MyVar = %MyVar"(显示变量值)
Action 2:Notify → "调试日志已记录"
或更精细的多变量同时输出:
Popup → "调试输出:\n%BATT = %BATT\n%TIME = %TIME\n%MyVar = %MyVar"
方法四:JavaScriptlet 里用 Popup 输出
var result = someCalculation();
tasker.popup("中间值:" + result, "调试");
tasker.returnValue(result);
变量命名与作用域
全大写 = 全局用户变量
%MYSETTING
%PROJECT_AUTO_ENABLED
%HOME_WIFI_SSID
全局变量:
- 所有 Profile/Task 可读可写
- 持久化存储(重启后还在)
- 存储在
tasker.db里
全小写 = 局部变量
%tmp
%result
%loopcount
局部变量:
- 仅当前 Task 内部可见
- Task 执行完自动销毁
- 不会出现在变量列表里
大小写混合 = 系统变量
Tasker 内置的系统变量用特定模式:
- 全大写(
%BATT、%WIFI、%TIME)— Tasker 自己管理 - 混合(
%LOC.alt、%VOLM、%HOME)— Tasker 自己管理 - 系统变量全只读,不能 Set
常见命名错误
- ❌
%MyVar和%myvar是两个不同变量(Tasker 变量区分大小写) - ❌
%BATT(系统变量)不能重新赋值 - ✅ 自定义全局变量建议用
%MY_前缀 - ✅ 避免和系统变量重名(虽然可以,但会造成混淆)
处理空值和未赋值的变量
变量引用不存在时
如果你引用了一个还没被设置的变量 %NotExists,Tasker 会直接把 %NotExists 当成字符串字面量输出(不会报错、不会显示空):
Popup → "值是 %NotExists"
→ 实际显示:"值是 %NotExists"(原封不动的字符串,不是空)
这种"静默失败"很难发现。
检查变量是否已赋值
If → %MyVar ~
# 匹配空字符串 = 未赋值或为空值
Popup → "变量未设置"
Else
Popup → "变量值:%MyVar"
Endif
~ 是正则匹配运算符,后面不带表达式 = 匹配空串。
在 Action 里检查
Variable Condition → %MyVar 不能为空
# 或
If → 变量值 %MyVar 模式匹配(正则) ^.+$(至少一个字符)
变量类型处理
Tasker 变量统一是字符串类型——不存在真正的整数/浮点数/布尔类型。数学运算时 Tasker 会自动解析:
Variable Set %A, "10"(字符串 "10")
Variable Math %A + 5 → 自动解析为数字 → 15
常见类型问题
问题一:字符串比较 vs 数字比较
If → %BATT < 20
# 正常工作:Tasker 会自动把两边都转成数字比较
If → %MyVar = hello
# 字符串比较,正常
但如果 %MyVar 里面有空格或特殊字符:
If → %MyVar = hello world
# 引号要转义吗?Tasker 里可以直接写
If → %MyVar ~ hello world
# 用正则匹配更安全(空格要转义吗?不用,正则里空格是字面量)
问题二:JSON 解析后的变量名
Read JSON Action 会根据 JSON 结构自动生成变量名:
JSON: {"user": {"name": "小明", "age": 25}}
→ %user_name = "小明"
→ %user_age = 25
嵌套越深,变量名越长。注意变量名可能和你自己定义的变量冲突。
问题三:数组变量(索引变量)
变量名末尾带数字(%ARR1、%ARR2、%ARR3)可以构成数组:
Variable Split %CSVContent → 按换行拆分
→ %CSVContent1 = "第一行"
→ %CSVContent2 = "第二行"
→ %CSVContent3 = "第三行"
判断数组长度:
# For 循环时,For → In 变量会自动识别数组元素
# 或用 JavaScriptlet:
var count = 0;
while (tasker.getLocal("%arr" + (count+1)) !== "") count++;
tasker.setGlobal("%ArrCount", count);
变量调试的进阶技巧
技巧一:写调试日志
在 Task 里加一个"调试日志"的 Variable Set,把关键变量值追加到日志文件:
Variable Set %DebugLog, "[时间 %TIME] BATT=%BATT WIFII=%WIFII Step=%Step"
Write File → 追加 %DebugLog 到 /sdcard/tasker-debug.log
技巧二:条件调试开关
用一个全局变量 %DEBUG = 1 控制调试输出:
If → %DEBUG = 1
Variable Set %LogMsg, "调试:%MyVar = %MyVar"
Write File → 追加到日志
Notify → "调试"
Endif
调试完把 %DEBUG 设为 0,所有调试输出自动消失。
技巧三:JavaScriptlet 里输出结构化数据
// 在 JavaScriptlet 里一次性输出多个变量
var debug = [
"BATT: " + tasker.getGlobal("%BATT"),
"TIME: " + tasker.getGlobal("%TIME"),
"APP: " + tasker.getGlobal("%APP"),
"MyVar: " + tasker.getLocal("%MyVar")
].join("\n");
tasker.popup(debug, "调试输出");
技巧四:变量断点
把 Task 里的某个 Action 替换成 Popup,加一个判断条件,就变成了类似"断点"的效果:
# 临时把 Action 5 改成:
If → %StepCounter = 3
Popup → "到达 Step 3,当前 %BATT = %BATT"
Wait → 手动确认后继续 10 秒
Endif
技巧五:跨 Task 变量追踪
如果 Task A 设置了 %Result,Task B 需要读取但发现是空的:
- 检查执行顺序:Task A 是不是在 Task B 之前执行了?
- 检查作用域:
%Result是全局还是局部?如果 Task A 里设成了局部变量,Task B 读不到 - 检查生命周期:Task A 执行完后局部变量会被销毁
变量值不更新的排查
症状
Profile 依赖的 %WIFII 变量值一直是旧值(比如还是上次的 Wi-Fi 名称)
或 %BATT 长时间显示同一个值
排查步骤
- 这是系统变量还是用户变量?
- 系统变量(
%BATT、%WIFII)由 Tasker 自动更新,不需要你 Set - 用户变量(
%MyVar)只有你 Set 了才会变
- 如果是系统变量,值不更新:
- Tasker 后台被杀了?→ 回后台被杀排查
- 电池优化限制了 Tasker 唤醒?→ 回电池优化设置
- 变量是不是全小写?全小写的系统变量有些不持久化
- 如果是用户变量,Set 了但没变:
- 是不是 Set 成了局部变量?
- Set 的时机对不对(比如 Set 之后又被覆盖了)
- Set Action 有没有条件(条件没满足所以没执行)
- 终极排查:
- 在 Tasker 菜单 → 数据 → 运行日志里搜索这个变量的名字
- 看有没有 Set / Read 的记录
- 有 Set 但值不对 → Set 的逻辑错了
- 根本没有 Set 记录 → Set Action 没执行(条件不满足、Task 没跑到这步)