问题描述
在 AutoJs6 6.7.0 (3804) 中,脚本通过 auto.registerEvent('window_content_changed', ...) 监听无障碍事件时,在微信小程序页面切换过程中偶发进程崩溃。AutoJs6 应用进程、无障碍服务和当前运行脚本会一起退出。
异常发生在 AccessibilityService 构造 AccessibilityEventWrapper 的阶段,早于脚本回调,因此脚本层的 try/catch 无法捕获或规避。
环境
- AutoJs6:6.7.0 (3804)
- Android:12
- 设备:OPPO PDYT20
- 上游源码:
master,ed3eb10e88db5a8425fd94bdddefa4176e5e1c94
- 无 Root、无 Shizuku;ADB 仅用于读取崩溃日志,不参与复现
最小复现脚本
'use strict';
auto();
auto.registerEvent('window_content_changed', function () {});
setInterval(function () {}, 1000);
复现步骤
- 确认 AutoJs6 无障碍服务已启用。
- 运行上述脚本。
- 打开微信中的美团小程序,反复切换页面或返回上一页。
- 节点树恰好在事件包装期间发生变化时,AutoJs6 进程退出,无障碍服务和脚本随之停止。
该问题具有竞态特征,可能需要多次切换页面才能触发。
实际结果
java.lang.ArrayIndexOutOfBoundsException: length=1; index=1
at android.util.LongArray.get(LongArray.java:174)
at android.view.accessibility.AccessibilityNodeInfo.getChild(AccessibilityNodeInfo.java:1114)
at org.autojs.autojs.core.automator.AccessibilityEventWrapper.getIndexInParent(AccessibilityEventWrapper.kt:32)
at org.autojs.autojs.core.automator.AccessibilityEventWrapper.<init>(AccessibilityEventWrapper.kt:17)
at org.autojs.autojs.core.accessibility.AccessibilityService.onAccessibilityEvent(AccessibilityService.kt:102)
期望结果
事件源节点在包装期间失效或已不再属于原父节点时,应返回安全的 indexInParent 哨兵值并继续处理后续事件,不应导致 AutoJs6 进程退出。
根因分析
AccessibilityEventWrapper.getIndexInParent() 当前从索引 0 开始查找事件源节点,但循环没有按 parent.childCount 限界:
var index = 0
val parent = node.parent ?: return 0
while (parent.getChild(index) != node) {
index++
}
return index
微信页面切换时无障碍节点树会发生竞态变化。如果事件源节点已从父节点移除,循环不会找到目标,并继续调用越界的 getChild(index)。Android 12 上最终由 LongArray.get() 抛出 ArrayIndexOutOfBoundsException。
建议将查找范围限制为父节点的 childCount,并对节点失效期间的运行时异常做防护;父节点为空、目标未找到或节点访问失败时返回 -1。该值与 UiObject 构造器的缺省 indexInParent 一致,用来表示没有可用的父级索引;本次不改变 UiObject 的其他导航行为。
问题描述
在 AutoJs6 6.7.0 (3804) 中,脚本通过
auto.registerEvent('window_content_changed', ...)监听无障碍事件时,在微信小程序页面切换过程中偶发进程崩溃。AutoJs6 应用进程、无障碍服务和当前运行脚本会一起退出。异常发生在
AccessibilityService构造AccessibilityEventWrapper的阶段,早于脚本回调,因此脚本层的try/catch无法捕获或规避。环境
master,ed3eb10e88db5a8425fd94bdddefa4176e5e1c94最小复现脚本
复现步骤
该问题具有竞态特征,可能需要多次切换页面才能触发。
实际结果
期望结果
事件源节点在包装期间失效或已不再属于原父节点时,应返回安全的
indexInParent哨兵值并继续处理后续事件,不应导致 AutoJs6 进程退出。根因分析
AccessibilityEventWrapper.getIndexInParent()当前从索引 0 开始查找事件源节点,但循环没有按parent.childCount限界:微信页面切换时无障碍节点树会发生竞态变化。如果事件源节点已从父节点移除,循环不会找到目标,并继续调用越界的
getChild(index)。Android 12 上最终由LongArray.get()抛出ArrayIndexOutOfBoundsException。建议将查找范围限制为父节点的
childCount,并对节点失效期间的运行时异常做防护;父节点为空、目标未找到或节点访问失败时返回-1。该值与UiObject构造器的缺省indexInParent一致,用来表示没有可用的父级索引;本次不改变UiObject的其他导航行为。