在自动化脚本的开发实践中,系统事件 与回调函数是连接脚本逻辑与外部环境变化的桥梁。与传统的轮询机制不同,冰狐平台提供了一套内置的系统事件回调体系------脚本无需主动、频繁地检查设备状态,当特定事件(如收到通知、切换应用、屏幕熄灭)发生时,系统会自动调用对应的回调函数。这种"事件驱动"的模式大幅降低了脚本的资源消耗,提升了响应实时性与代码的可维护性。
一、系统事件回调的设计理念
冰狐JS是专为移动端自动化设计的JavaScript子集,它在保留核心语法的基础上,剔除了闭包、匿名函数、位运算等复杂特性,同时新增了适配移动端自动化的编译指令与系统回调函数。系统事件回调的核心设计理念可以概括为两点:
-
自动触发,无需轮询 :开发者只需定义好回调函数,当系统检测到对应事件时自动执行,无需在
main函数中编写循环监听代码。 -
与主线程隔离,通过全局变量通信 :系统回调函数运行在与
main不同的线程中,如需在回调与主脚本之间传递数据,可通过__global关键字声明全局变量来实现。
这一设计使得脚本逻辑更加清晰------主流程专注于核心业务,回调函数负责响应外部变化。
二、UI生命周期回调
冰狐的UI系统使用XML描述界面、使用JS处理UI事件。在UI的生命周期中,平台提供了两个关键的系统回调函数:
2.1 onUIResume
onUIResume是系统回调函数,当UI加载完成后系统会自动调用。这一回调最常见的用途是在UI渲染完成后执行数据加载或界面初始化操作。
// UI加载完成后自动执行
function onUIResume() {
// 获取列表控件实例并加载数据
var listview = ui('lv');
listview.addData(['数据项1', '数据项2', '数据项3']);
console.log('UI加载完成,数据已填充');
}
实践要点 :所有列表数据加载、修改操作,必须 放在onUIResume回调中执行,避免UI未渲染完成时获取控件失败。此外,UI中不能执行耗时操作,具体的耗时任务应通过runTask另起线程执行。
2.2 onUIPause
onUIPause是与onUIResume对应的系统回调函数,当UI界面消失(如被关闭或覆盖)时系统会自动调用。它通常用于释放资源、保存状态或停止后台任务:
function onUIPause() {
console.log('UI已关闭,释放相关资源');
// 停止轮询、保存临时数据等
}
2.3 onBackPressed
当用户按下设备的返回键时,系统会自动调用onBackPressed回调函数。开发者可以在其中自定义返回行为,例如弹出确认对话框、保存数据后再退出等:
function onBackPressed() {
// 自定义返回键行为
console.log('用户按下返回键');
// 可在此处执行保存操作或弹出提示
}
三、设备状态与系统事件回调
冰狐平台内置了多套面向设备状态的系统回调函数,覆盖了通知、窗口切换、屏幕状态等常见场景。
3.1 cbNotification------通知监听
cbNotification是用于监听系统通知的回调函数。当设备收到新的通知时,系统自动触发该回调。这一能力在需要根据通知内容触发自动化操作的场景中尤为实用------例如检测到特定APP的推送消息后自动执行相应任务。
// 收到通知时自动触发
function cbNotification(notification) {
console.log('收到通知:' + notification);
// 根据通知内容执行相应逻辑
}
使用该功能的前提是已在设备上开启冰狐的通知读取权限。
3.2 cbWindowChange------窗口切换监听
cbWindowChange用于监听当前窗口(即前台应用或界面)的切换事件。当用户从A应用切换到B应用,或从当前页面跳转到另一页面时,系统自动触发该回调。
function cbWindowChange(windowInfo) {
console.log('窗口已切换:' + windowInfo);
// 根据当前窗口执行相应适配逻辑
}
该回调在需要感知应用切换、实现跨应用自动化流程时非常关键。
3.3 cbScreenStateChange------屏幕状态监听
cbScreenStateChange用于监听设备的亮屏与熄屏状态变化。当屏幕亮起或熄灭时,系统自动触发该回调:
function cbScreenStateChange(state) {
if (state === 'on') {
console.log('屏幕已点亮');
} else {
console.log('屏幕已熄灭');
}
}
在需要根据屏幕状态决定是否继续执行操作的场景(如息屏时暂停任务以节省电量)中,该回调具有重要的实用价值。
3.4 cbFloatButton------悬浮按钮回调
冰狐支持开发者配置自定义悬浮按钮,cbFloatButton是点击该悬浮按钮时系统自动触发的回调函数。通过configFloatButton函数可以配置悬浮按钮的显示与行为。
function cbFloatButton(id, text) {
console.log('悬浮按钮点击 - id:' + id + ' text:' + text);
// 执行快捷操作,如启动/停止脚本
}
重要注意 :悬浮按钮回调函数中不能 直接调用callScript(同步调用),否则会导致UI阻塞。如需执行异步任务,应使用runTask函数。
3.5 cbForceExit------强制退出回调
当脚本被强制停止时,系统会自动触发cbForceExit回调。开发者可以在此回调中执行必要的清理工作,如释放资源、保存状态、记录退出日志等:
function cbForceExit() {
console.log('脚本被强制停止,执行清理操作');
// 释放文件句柄、保存中间数据等
}
四、回调函数与多线程的数据通信
如前所述,系统回调函数运行在与main不同的线程中。如果需要在回调函数与主脚本之间传递数据,冰狐提供了__global关键字来声明全局变量:
// 在主脚本中声明全局变量
__global.status = 'idle';
// 在回调函数中修改全局变量
function cbNotification(notification) {
__global.status = 'notification_received';
__global.lastNotification = notification;
}
// 在主脚本中读取全局变量
function main() {
while (true) {
if (__global.status === 'notification_received') {
console.log('处理通知:' + __global.lastNotification);
__global.status = 'idle';
}
sleep(1000);
}
}
这种通过全局变量实现的跨线程通信机制,是冰狐脚本中连接主流程与事件回调的标准方式。
五、实践建议
基于冰狐的系统事件与回调机制,以下实践建议可供参考:
-
UI数据加载务必在
onUIResume中完成:确保界面渲染完成后再操作控件,避免获取控件失败。 -
回调中避免耗时操作 :系统回调应保持轻量,耗时任务应通过
runTask另起线程执行。 -
善用
__global进行跨线程通信:回调函数与主脚本之间的数据传递,统一通过全局变量实现。 -
合理组合多个回调 :复杂场景下可同时使用多个系统回调,例如通过
cbWindowChange感知应用切换,再通过cbNotification响应特定通知,实现完整的自动化闭环。
冰狐的系统事件与回调机制,以简洁的API设计将设备环境的变化无缝嵌入脚本逻辑之中。开发者只需掌握上述回调函数的定义与使用规范,便能构建出响应灵敏、资源高效的自动化脚本------无需轮询、无需复杂的线程管理,让脚本真正"感知"外部世界的变化。