Java 遍历AccessibilityNodeInfo时Android可访问性服务中的无限递归

Java 遍历AccessibilityNodeInfo时Android可访问性服务中的无限递归,java,android,accessibilityservice,Java,Android,Accessibilityservice,我的应用程序的用户在几天后就遇到了崩溃。我能够在我的设备上收集logcat,并添加了一些调试输出。下面是正在发生的事情: 在我的handleAccessibilityEvent()中,我调用 AccessibilityNodeInfo root = getRootInActiveWindow(); int eventWindowId = event.getWindowId(); if (ExistsNodeOrChildren(root, new WindowIdCondition(eventW

我的应用程序的用户在几天后就遇到了崩溃。我能够在我的设备上收集logcat,并添加了一些调试输出。下面是正在发生的事情:

在我的
handleAccessibilityEvent()
中,我调用

AccessibilityNodeInfo root = getRootInActiveWindow();
int eventWindowId = event.getWindowId();
if (ExistsNodeOrChildren(root, new WindowIdCondition(eventWindowId)))
{
}
它递归地遍历节点树:

private boolean ExistsNodeOrChildren(AccessibilityNodeInfo n, NodeCondition condition) 
{
    Log.d(_logTag, "ExistsNodeOrChildren" + n.toString());
    if (n == null) return false;
    if (condition.check(n))
        return true;
    for (int i = 0; i < n.getChildCount(); i++)
    {
        Log.d(_logTag, "ExistsNodeOrChildren child" + i);
        if (ExistsNodeOrChildren(n.getChild(i), condition))
            return true;
    }
    return false;
}

如果这不是由NodeCondition函数(您可能应该提供)中的其他递归引起的,并且这实际上是Android OS虚拟视图层次结构中的一个错误,那么您可以尝试通过执行以下操作来修复它:

private boolean ExistsNodeOrChildren(AccessibilityNodeInfo n, NodeCondition condition) {

    //For God sake do this first if you think n might actually be null!!!
    //Or just don't do it, and let n.toString() throw a NPE. (BAD IDEA)
    if (n == null) return false; 

    Log.d(_logTag, "ExistsNodeOrChildren" + n.toString());

    //NOTE: This could also cause recursion, you didn't provide this code.
    if (condition.check(n)) return true;

    for (int i = 0; i < n.getChildCount(); i++) {
        AccessibilityNodeInfo child = n.getChild(i);

        //Skip recursion the times n.getChild() returns n.
        //The check really is this simple, because we can only skip this
        //When the child is literally the same object, otherwise it might be
        //a node that has identical properties, which can happen.
        if (child != n) {
            Log.d(_logTag, "ExistsNodeOrChildren child" + i);
            if (ExistsNodeOrChildren(n.getChild(i), condition)) return true;
        } else {
            log.e("We should report this as a bug in the AOSP");
        }
    }

    return false;
}
private boolean ExistsNodeOrChildren(AccessibilityNodeInfo,NodeCondition条件){
//看在上帝的份上,如果你认为n实际上可能是空的,请先这样做!!!
//或者干脆不做,让n.toString()抛出一个NPE。(坏主意)
如果(n==null)返回false;
Log.d(_logTag,“ExistsNodeOrChildren”+n.toString());
//注意:这也可能导致递归,您没有提供此代码。
if(条件检查(n))返回true;
对于(int i=0;i
嘿,菲利普。从Chrome 1月25日的更新开始,bitwarden也出现了类似的问题。请参阅我发现的另一个可能相关的bug:次要注释(n.toString())后跟n==null检查?真可疑!但最终是不相关的。
private boolean ExistsNodeOrChildren(AccessibilityNodeInfo n, NodeCondition condition) {

    //For God sake do this first if you think n might actually be null!!!
    //Or just don't do it, and let n.toString() throw a NPE. (BAD IDEA)
    if (n == null) return false; 

    Log.d(_logTag, "ExistsNodeOrChildren" + n.toString());

    //NOTE: This could also cause recursion, you didn't provide this code.
    if (condition.check(n)) return true;

    for (int i = 0; i < n.getChildCount(); i++) {
        AccessibilityNodeInfo child = n.getChild(i);

        //Skip recursion the times n.getChild() returns n.
        //The check really is this simple, because we can only skip this
        //When the child is literally the same object, otherwise it might be
        //a node that has identical properties, which can happen.
        if (child != n) {
            Log.d(_logTag, "ExistsNodeOrChildren child" + i);
            if (ExistsNodeOrChildren(n.getChild(i), condition)) return true;
        } else {
            log.e("We should report this as a bug in the AOSP");
        }
    }

    return false;
}