Repository navigation
Description
环境
- AutoJs6 6.7.0
- Android 16 (API 36),Redmi / HyperOS 3
- 无 root、无 Shizuku,仅 A11Y
关联
关联 #343、#466。本文不是重复提问。#343 中已用 com.miui.home + 900ms 时间窗回避了"从后台回应用时包名记为桌面"的问题,但该方案依赖单机硬编码。下面补充一个 #343 未覆盖的判定维度(窗口类名),以及误判的时序成因。
现象
用 A11Y 事件做前台感知时,三类不稳定:
- 从应用切回桌面后,
currentPackage()滞后,期间仍返回上一个应用 - 从最近任务(Recents)返回应用时,被误判为"回到桌面",状态闪断
- launcher 事件可能在应用事件之后"补发",导致刚判定完上岛又被清空
发现
1. 同一 launcher 包名下,类名可区分「桌面本体」与「最近任务」
实测日志(com.android.launcher):
桌面本体 com.android.launcher / com.android.launcher.Launcher
最近任务卡片 com.android.launcher / android.widget.ListView
这两者包名完全相同,仅类名不同。因此只按包名判断"是否回到桌面"会把打开最近任务列表误判为已回桌面。
注意:本机最近任务窗口的类名是 android.widget.ListView,而非 RecentsActivity 之类。这说明类名特征因 ROM 而异,建议同时维护
- 桌面类名白名单:
Launcher/Home/Workspace - 最近任务类名特征:
Recents/Quickstep/Overview/TaskView/RecentApps
并在无法匹配时降级为"不判定",而非强行判定。
2. launcher 事件会晚于应用事件到达
从最近任务点卡片返回应用,实测序列:
[22:54:42] EVT com.android.launcher / android.widget.ListView
[22:54:42] EVT com.tencent.ima / com.tencent.ima.MainActivity
[22:54:43] 焦点已是 com.tencent.ima,但事件源仍报 com.android.launcher
[22:54:44] ~ [22:54:46] 同上报错状态持续
即:应用已获得焦点,launcher 的事件还在后面补发,持续约 4 秒。任何"看到 launcher 包名就认为回桌面"的实现,都会在这段窗口内误清空状态。
而从桌面点图标进入应用则是相反顺序:
[22:57:44] EVT com.android.launcher / com.android.launcher.Launcher (连续多条)
[22:57:48] EVT org.autojs.autojs6 / ...MainActivity
应用事件最后到达,判定稳定。
结论:事件到达顺序本身就是可用信号,不必靠固定延时去猜。
3. 事件包名可能与真实前台不一致
同一份日志中,事件上报 com.android.launcher,但当时的控件树全部属于目标应用:
⚠ 事件=com.android.launcher 但控件里有 com.tencent.ima
⚠ 事件=com.android.launcher 但控件里有 org.autojs.autojs6
这说明窗口层级退出过程中残留的 launcher 事件,其包名不能直接等同于当前前台。
复现
events.on("window_state_changed", function (e) {
log(e.getPackageName() + " / " + e.getClassName()
+ " | currentPackage=" + currentPackage());
});
依次操作:① 桌面点图标进应用 ② 返回桌面 ③ 打开最近任务 ④ 从最近任务点卡片回应用,对比四种路径的事件顺序与 currentPackage() 返回值。
建议
- 文档补充示例:给出"用 launcher 包名 + 类名区分桌面/最近任务"的推荐写法,含类名匹配失败时的降级策略
- 提供便捷 API:内置常见 launcher 包名集合,提供
isLauncher(pkg)/isRecentsWindow(cls)之类的判断 - 事件驱动的前台获取:除
currentPackage()外,考虑提供基于窗口事件维护的前台包名(无事件时零开销),比定时轮询更准也更省电 - 无特权场景的价值:v6.1 对 currentPackage 准确性的优化走的是 Shizuku > Root > A11Y 优先级,但多数用户既无 root 也无 Shizuku。上述判定完全基于 A11Y 事件,可作为无特权环境下的兜底方案
附
我用上述逻辑写了一套开源的灵动岛方案(AutoJs6 脚本 + 一个极小的通知中转 App,用于绕过 AutoJs6 清单无法声明 POST_PROMOTED_NOTIFICATIONS 的限制):
https://github.com/Little-JohnKhan/notification-island
其中 scripts/island_daemon.js 的回桌面判定按上面三层写的(类名过滤 → 延时复核 → 期间事件撤销),实测把"切应用必闪"降为基本不出现。
Activity
Little-JohnKhan commentedon Oct 19, 2026
说明:上述行为源于系统无障碍事件机制与 launcher 实现,并非 AutoJs6 的实现问题。此处仅建议在文档中补充判定方案,减少使用者重复踩坑。