UI Tree 元素读取:Operit 怎么精准定位屏幕控件
UI Tree 是什么
UI Tree 是 Android 无障碍服务 API 提供的当前界面元素层级树——每个可见控件(按钮、文本框、图片等)都是树里的一个节点,节点包含控件类型、文本内容、坐标、可点击性等属性。
Operit 通过 uiautomator dump 或直接调用 AccessibilityService API 获取这棵树,然后解析、定位目标元素。这是它最精准的定位通道——不依赖视觉模型,不怕界面风格变化。
树的节点结构(简化示意)
<hierarchy rotation="0">
<node class="android.widget.FrameLayout" bounds="[0,0][1080,2400]">
<node class="android.widget.LinearLayout" bounds="[0,0][1080,120]">
<node class="android.widget.TextView"
text="微信"
content-desc=""
clickable="false"
bounds="[40,30][200,90]"/>
</node>
<node class="android.widget.RecyclerView" bounds="[0,120][1080,2400]">
<node class="android.widget.LinearLayout"
clickable="true"
bounds="[0,120][1080,200]">
<node class="android.widget.TextView" text="张三(第 3 条)"/>
<node class="android.widget.TextView" text="文件: 报告.pdf"/>
</node>
</node>
</node>
</hierarchy>
Operit 拿到这个 XML 后:
- 按路径搜索目标节点(如找
text包含「报告」的可点击节点) - 读取节点的
bounds(坐标) - 模拟点击该坐标
定位元素的常用方法
| 方法 | 说明 | 示例 |
|---|---|---|
按 text 匹配 | 找显示文字等于或包含某值的节点 | 「点击 text=保存 的按钮」 |
按 content-desc 匹配 | 无障碍描述属性,部分应用用它标注控件 | 「点击 content-desc=搜索 的图标」 |
按 class 匹配 | 控件类型(TextView/Button/ImageView 等) | 「找所有可点击的 ImageView」 |
| 按坐标范围 | 直接指定屏幕坐标或范围 | 「点击屏幕底部中间区域」 |
| 组合条件 | 同时满足多个条件 | 「找 clickable=true 且 bounds 在屏幕下半部的 TextView」 |
Operit 对话里的实际用法
你不用自己写 XPath 或解析 XML。直接用自然语言描述:
「打开微信,找到第 3 条聊天记录里的文件,保存到网盘」
Operit Agent 内部做的事:
- 启动微信(通过 Launcher 方式或无障碍)
- dump 当前 UI Tree
- 找到聊天列表的第 3 条可点击项
- 进入该聊天,dump UI Tree
- 找到包含文件的消息气泡,点击打开
- 在文件预览界面找「保存到网盘」或类似操作
- 执行完成后返回结果
中间每一步如果 UI Tree 没有覆盖(比如微信用了 Canvas 绘制的聊天项),Agent 会自动回退到 AutoGLM 视觉路径。
UI Tree 的局限
- Canvas / SurfaceView:游戏界面、部分视频播放器、自定义 Canvas 绘制的控件,UI Tree 里可能只剩一个大节点或完全缺失
- WebView 内容:部分应用内嵌的 WebView 界面,UI Tree 只能拿到 WebView 容器,内部 DOM 拿不到
- 系统 UI:Android 系统级对话框(权限请求、通知、快捷设置),可能受限于系统版本和厂商定制
- 性能:频繁 dump UI Tree 会有轻微性能开销,Operit 内部做了节流
和 AutoGLM 的配合
当 UI Tree 路径覆盖不到时,Operit 自动回退到 AutoGLM 视觉理解——截图发给视觉模型,让它判断要点哪里。两条路径的配合是 Operit UI 自动化比别家更稳的关键。