java - AccessibilityNodeInfo 的生命周期是怎样的?

标签 java android accessibilityservice

我正在开发一个 Android 应用程序,其中包含辅助功能服务,允许用户创建“宏”,该宏可以快速、自动地执行他们经常使用他们已经使用的第三方应用程序执行的任务(而不必与某些对讲服务交互,在该服务中,他们等待事物被列出,然后必须在非常缓慢的过程中一遍又一遍地说出他们想要它做的每件事)。我的问题是,我似乎无法找到有关 AccessibilityNodeInfo 对象生命周期的详细文档。例如,如果宏设置为“打开此应用程序并单击“执行”按钮,然后列出所有结果”,我可能需要等待并收集应用程序中的增量更新,因为结果可能会跨多个 WINDOW_CONTENT_CHANGED 事件出现,每个事件仅包含应用程序正在构建的总结果列表的子集。我可以使用 findViewById 之类的东西来获取我想要的元素,但是将它们保留在多个事件中是一个坏主意,因为 android 操作系统可以随时使它们无效/更改它们?我想知道是否有任何我错过的文档/示例,可以更清楚地说明如何最好地交互accessibilityNodeInfo对象,以及如何/是否可以随着时间的推移缓存或收集它们,以获得应用程序布局中内容的更完整和一致的图片。

我看过有关accessibilitynodeinfo的其他帖子,例如( Android AccessibilityNodeInfo refresh() and recycle() ),但这仍然不能回答诸如节点何时无效或如果我不回收节点并稍后尝试使用它会发生什么(特别是如果该元素已被应用程序删除)之类的问题。我想要回答的问题属于以下代码中的类型:

//for caching nodes... bad idea?
HashMap<String,AccessibilityNodeInfo> cachedNodes = new HashMap<>();

//gets fired for lots of reasons, can contain arbitrary subsets of the total app layout hierarchy (appears upper bounded by what is visible on the screen)
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
    // my accessibility service is listening to all event types
    AccessibilityNodeInfo nodeInfo = event.getSource();
    //sometimes the node is just totally null... why??
    if(nodeInfo != null){
        //what is this really doing? Why is this node sometimes different from traversing up the hierarchy with getParent() manually?
        rootNode = getRootInActiveWindow();
        if(rootNode == null) {
            rootNode = nodeInfo;
            AccessibilityNodeInfo parent = nodeInfo.getParent();
            while(parent != null){
                rootNode = parent;
                parent = rootNode.getParent();
            }
        }
        //It appears this method returns all matches in the event hierarchy regardless of which node you call it on?
        List<AccessibilityNodeInfo> nodesOfInterest = rootNode.findAccessibilityNodeInfosByViewId("package.name/id_of_nodes_i_want");
        for(AccessibilityNodeInfo node: nodesOfInterest){
            //my accessibility service is set up to be able to get view ids and retrieve window content, but view ids are not unique
            // may have to compose an ID based on the view type lineage of the node?
            if(!cachedNodes.containsKey(getUniqueID(node)){
                cachedNodes.put(getUniqueID(node),node);
            }
        }
    }

}

最佳答案

AccessibilityNodeInfo 或 AccessibilityNodeInfoCompat (用于后台兼容性) 不是 View 。

当您打开手机的任何屏幕时,其称为“窗口”的内容,该内容以可访问性节点信息树的形式呈现。

有时您得到的 AccessibilityNodeInfo 为 null,但刷新后,您可以获得该特定节点的值。

accessibilityNodeInfo.refresh();

使用它所代表的 View 的最新状态刷新此信息。

您可以访问此处以获取更多信息。 Accessibility Node Info

关于java - AccessibilityNodeInfo 的生命周期是怎样的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56993925/

相关文章:

java - 调试期间调用 MethodHandle

android - 如何使用我的 android 应用程序在谷歌驱动器上上传文件

android - 如何在viewpager中的位置1设置选项卡

android - AccessibilityNodeInfo.performAction() 方法有时不起作用

android - 想要从另一个应用程序检索屏幕上每个可见和可点击的 View ,包括使用无障碍服务的 recyclerView 的项目 View

java - java FileDescriptor .sync() 用于*读取*文件的逆向

java - 切换条件在 Android 中不起作用

java - 使用数组在组合模型中链接打印的方法

android - Could not inflate and Didn't find class Behavior of android支持设计BottomSheetBehavior

android - 检测我的无障碍服务是否启用