无论如何要知道这个不确定的循环是否在 Java 内完成?

Anyway to know if this indeterminate loop is finished in Java?

我正在尝试通过无障碍服务抓取 Android 上的可见元素。我希望将元素的详细信息存储到一个数组中,以便稍后同时处理。

此特定循环用于查找元素的 parents、它们的 children 以及它们的 children 的 children。它可以生成 30 个循环,遍历自身直到找到最低的 child。假设我有另一个线程在等待处理那个完整的数组,它怎么知道数组何时准备好?

这是没有硬编码变量的情况。没有尺寸参考,也没有我能想到使用的任何其他明显的结尾签名。我试过计算重复次数和 null children,但它要么不准确,要么不确定。

谢谢,

public void nodeToArray(int id, AccessibilityNodeInfo node) {
        final String TCLASS = "nodeToArray";
        int count = node.getChildCount();
        for (int i = 0; i < count; i++) {
            AccessibilityNodeInfo child = node.getChild(i);
            if (child != null) {
                if (child.isVisibleToUser()) {
                    ArrayList<String> childAttrs = new ArrayList<>();
                    if ( child.getPackageName() != null ) { childAttrs.add( child.getPackageName().toString().trim() ); } else { childAttrs.add(""); } //package
                    if ( child.getClassName() != null ) { childAttrs.add( child.getClassName().toString().trim() ); } else { childAttrs.add(""); } //class
                    if ( child.getViewIdResourceName() != null ) { childAttrs.add( child.getViewIdResourceName().trim() ); } else { childAttrs.add(""); } //id
                    if ( child.getText() != null ) { childAttrs.add( child.getText().toString().trim() ); } else { childAttrs.add(""); } //text
                    if ( child.getContentDescription() != null ) { childAttrs.add( child.getContentDescription().toString().trim() ); } else { childAttrs.add(""); } //desc
                    Rect r = new Rect();
                    child.getBoundsInScreen(r);
                    childAttrs.add( r.left + "/" + r.top + "/" + r.right + "/" + r.bottom ); //bounds
                    //
                    if ( queryMap.size() == 0 ) {
                        queryMap.put( 0, childAttrs );
                    } else {
                        queryMap.put( queryMap.size(), childAttrs );
                    }
                    //
                    nodeToArray(id, child);
                    child.recycle();
                }
            }
        }
        CommonUtils.Echo("ScreenStater", TCLASS, "id:"+ id + " - size:" + queryMap.size(), 1);
    }
2021-09-22 17:39:43.187 27601-27786/com.example.accessibility_test I/ScreenStater-processArray: processing:23
2021-09-22 17:39:43.247 27601-27601/com.example.accessibility_test I/ScreenStater-nodeToArray: id:788 - size:8
2021-09-22 17:39:43.248 27601-27601/com.example.accessibility_test I/ScreenStater-nodeToArray: id:788 - size:9
2021-09-22 17:39:43.248 27601-27601/com.example.accessibility_test I/ScreenStater-nodeToArray: id:788 - size:11
2021-09-22 17:39:43.248 27601-27601/com.example.accessibility_test I/ScreenStater-nodeToArray: id:788 - size:12
2021-09-22 17:39:43.248 27601-27601/com.example.accessibility_test I/ScreenStater-nodeToArray: id:788 - size:12
2021-09-22 17:39:43.248 27601-27601/com.example.accessibility_test I/ScreenStater-nodeToArray: id:788 - size:18
2021-09-22 17:39:43.248 27601-27601/com.example.accessibility_test I/ScreenStater-nodeToArray: id:788 - size:19
2021-09-22 17:39:43.249 27601-27601/com.example.accessibility_test I/ScreenStater-nodeToArray: id:788 - size:19
2021-09-22 17:39:43.249 27601-27601/com.example.accessibility_test I/ScreenStater-nodeToArray: id:788 - size:20
2021-09-22 17:39:43.249 27601-27601/com.example.accessibility_test I/ScreenStater-nodeToArray: id:788 - size:21
2021-09-22 17:39:43.249 27601-27601/com.example.accessibility_test I/ScreenStater-nodeToArray: id:788 - size:22
2021-09-22 17:39:43.249 27601-27601/com.example.accessibility_test I/ScreenStater-nodeToArray: id:788 - size:23
2021-09-22 17:39:43.249 27601-27601/com.example.accessibility_test I/ScreenStater-nodeToArray: id:788 - size:23

您需要一些实际线程间通信的方法。

你展示的代码最终会产生一些东西,数组。另一个线程需要 (a) 等待,并且 (b) 接收数组。

Java 中有几个 Future 机制来支持这种用法。我建议 CompletableFuture 作为一个很好的例子。

无论启动此机制的是什么,都会创建一个 CompletableFuture 并使其可供生产者和最终消费者使用。生产者将 'complete' 完成后的未来,消费者将等待(或以其他方式安排接收通知)完成。

由于 nodeToArray 是(同步)递归的,因此您只能在最顶层完成 Future。