ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

uiautomator2 官方 API 详解:Device、Session 与 XPath 三大核心类的完整使用指南

2026/9/25 15:45:06 拓冰建站 浏览量
uiautomator2 官方 API 详解:Device、Session 与 XPath 三大核心类的完整使用指南 测试移动开发GUI 自动化【免费下载链接】uiautomator2Android Uiautomator2 Python Wrapper项目地址https://gitcode.com/gh_mirrors/ui/uiautomator2点击查看免费下载本文基于 uiautomator2 仓库的 API 文档docs/api.rst与源码实现展开系统讲解官方文档中自动生成的三大核心类——uiautomator2.Device、uiautomator2.Session、uiautomator2.xpath.XPath——的连接方式、设备控制接口、元素选择器、应用生命周期管理与 XPath 插件用法。读完后你可以脱离图形化工具直接用 Python API 完成连接设备、截图、点击、输入、应用管理、滚动查找元素等 Android UI 自动化全流程。一、文档定位api.rst 覆盖了哪些 API官方 API 文档由 Sphinx 的autodoc指令生成docs/api.rst 全文只声明了三个自动文档化目标.. autoclass:: uiautomator2.Device :members: .. autoclass:: uiautomator2.Session :members: .. autoclass:: uiautomator2.xpath.XPath :members:这明确了官方 API 的三根主线Device设备控制器、Session应用保活会话、XPathXPath 查询插件。docs/index.rst 将其归入“常用接口”章节构建配置见 docs/conf.py。以下全部内容均按此三主线组织并逐一对照源码给出可验证的实现细节。二、连接设备connect 与 Device 的类结构2.1 连接入口uiautomator2包在 uiautomator2/init.py#L1086-L1119 提供两个连接函数import uiautomator2 as u2 d u2.connect() # 使用环境变量 ANDROID_SERIAL 或默认设备 d u2.connect(10.0.0.1:5555) # 无线 ADB 设备 d u2.connect(cff1123ea) # USB 设备序列号 d u2.connect_usb(cff1123ea) # 等价于 connect从源码看connect()未传参时读取环境变量ANDROID_SERIAL最终统一走connect_usb()若仍无序列号则取adbutils.adb.device()返回的默认在线设备。连接超时由模块级常量WAIT_FOR_DEVICE_TIMEOUT控制默认 20 秒L37等待设备上线失败会抛出ConnectError。对无线设备IP:PORT格式_wait_for_device会在超时窗口内每秒尝试disconnect connect重连这解释了为什么断线后的无线设备可以靠重试恢复。2.2 Device 的 Mixin 结构Device类定义于 uiautomator2/init.py#L1043class Device(_Device, _AppMixIn, _PluginMixIn, InputMethodMixIn, _DeprecatedMixIn): Device object pass这是一个典型的能力分层结构理解它就能快速定位任意 API 的归属_BaseClientL52-L221最底层能力含shell、push、pull、reset_uiautomator、jsonrpc动态调用包装器、info、device_info、wlan_ip等_DeviceL222-L638屏幕与输入含window_size、screenshot、dump_hierarchy、click、swipe、press、send_keys、orientation等_AppMixInL641-L933应用生命周期含app_start、app_stop、app_install、app_info、session等_PluginMixInL1013-L1040插件式属性d.watcher、d.xpath、d.image、d.screenrecord、d.swipe_ext、d.watch_context()InputMethodMixInuiautomator2/_input.pyset_input_ime、send_action等基于 AdbKeyboard 输入法的输入能力_DeprecatedMixInwait_timeout属性、unlock()、toast、make_toast等保留的旧接口。2.3 基础控制接口接口说明源码位置d.shell(cmd, timeout60)在设备执行 shell返回ShellResponse(output, exit_code)异常抛AdbShellErrorL120-L141d.info通过jsonrpc.deviceInfo获取设备状态screenOn、displayRotation等L143-L145d.window_size()返回(width, height)元组L227-L230d.screenshot(filenameNone, formatpillow)返回PIL.Image或 OpenCV 格式 ndarray传filename时保存文件并返回 None多屏设备可指定display_idL232-L263d.dump_hierarchy(compressedFalse, prettyFalse)导出视图层级 XML空层级会自动重试 3 次retry装饰器L265-L304d.push(src, dst, mode0o644)/d.pull(src, dst)文件推送到设备 / 从设备拉取L202-L220d.reset_uiautomator()停止并重启设备端 uiautomator 服务keeper → force-stop → am instrument → 等待就绪L189-L200截图的底层链路值得注意screenshot()优先调用jsonrpc.takeScreenshot(1, 80)第 1 个参数为压缩级别、80 为质量拿到 base64 后解码为PIL.Image当服务端返回 None 时回退到adbutils的 screencap 通道。2.4 输入与手势接口所有坐标接口都经过pos_rel2absL319-L342转换小于 1 的坐标值视为百分比即d.click(0.5, 0.5)表示点击屏幕中心。d.click(0.5, 0.5) # 点击中心也可用像素坐标 d.double_click(x, y) # 双击 d.long_click(x, y, duration.5) # 长按 d.swipe(0.5, 0.8, 0.5, 0.2) # 从 (0.5,0.8) 滑到 (0.5,0.2) d.swipe(0.5, 0.8, 0.5, 0.2, duration1.0) # 显式指定时长 d.swipe_points([(200,300),(210,320)], duration0.5) # 多点路径 d.drag(0.5, 0.8, 0.5, 0.2, duration0.5) # 拖拽 d.press(home) # home/back/menu/enter/volume_up 等按键名 d.press(4, 1) # keycode meta d.long_press(back) # 长按按键等价 input keyevent --longpress d.keyevent(wakeup) # 执行 input keyevent WAKEUP关于swipe的实现细节L420-L448Android 端UiDevice.swipe以steps为节奏单位每步约 5ms因此 Python 侧将duration换算为steps duration * 200默认值取SCROLL_STEPSduration与steps同时传入时会告警并优先使用steps。步骤数至少为 2否则没有滑动效果。文本输入方面send_keysL593-L610采用两级策略优先走剪贴板通道setClipboardpasteClipboard无需切换输入法若getClipboard校验值不一致则回退到 AdbKeyboard 输入法广播通道见 uiautomator2/_input.py#L99-L111失败后再回退到d(focusedTrue).set_text()。配合的clear_text()同样有 jsonrpcclearInputText与 IME 兜底双路径。2.5 应用管理接口_AppMixIn提供了完整的应用生命周期 APId.app_current() # {package: ..., activity: ..., pid: ...} d.app_start(com.example.app) # monkey 方式启动 d.app_start(com.example.app, activity.Main, waitTrue, stopTrue) d.app_wait(com.example.app, timeout20, frontFalse) d.app_list(filterNone) # pm list packages d.app_list_running() # 运行中的应用安装列表 ∩ ps 进程 d.app_stop(com.example.app) d.app_stop_all(excludes[]) # 杀掉除 uiautomator 自身外的三方应用 d.app_clear(com.example.app) # pm clear d.app_uninstall(com.example.app) d.app_install(app.apk) # 支持路径、URL 或文件对象 d.app_info(com.example.app) # {versionName: ..., versionCode: ...} d.app_auto_grant_permissions(com.example.app) # 自动授予运行时权限需 Android 6.0/targetSdk≥22 d.wait_activity(com.example.app.MainActivity, timeout10)几个实现要点app_start在未指定activity或use_monkeyTrue时使用monkey -p pkg -c android.intent.category.LAUNCHER 1否则走am start -n pkg/activityL721-L765app_list_running依赖ps -A部分设备不支持时自动降级为ps_compat_shell_psL656-L663。其他设备状态接口包括d.screen_on()/d.screen_off()唤醒/息屏、d.orientation读写natural/left/right/upsidedown倒转需 API 18、d.freeze_rotation(True)、d.last_toast/d.clear_toast()、d.open_notification()/d.open_quick_settings()、d.open_url(url)L508-L563。三、UiObject选择器式元素定位d(text...) 语法Device.__call__L637-L638把d(text确定)这种调用映射为UiObject(self, Selector(**kwargs))这是 uiautomator2 最标志性的用法定义在 uiautomator2/_selector.py。3.1 Selector 支持的全部字段Selector.__fieldsL17-L43定义了可传入d(**kwargs)的完整字段集每个字段带一个位掩码类别字段文本text,textContains,textMatches,textStartsWith内容描述description,descriptionContains,descriptionMatches,descriptionStartsWith类名className,classNameMatches包名packageName,packageNameMatches资源 IDresourceId,resourceIdMatches状态位checkable,checked,clickable,longClickable,scrollable,enabled,focusable,focused,selected实例index,instance传入未知字段会抛ReferenceError这保证了选择器拼写错误在本地就被发现。多条件按 AND 组合还支持child()/sibling()构建层级关系obj d(text设置, description设置入口) # AND 组合 obj d(resourceIdcom.android.settings:id/title, instance0) obj d(scrollableTrue).child(textWi-Fi) # 在可滚动元素内找子节点 for item in d(classNameandroid.widget.TextView): # UiObject 可迭代 print(item.info)3.2 UiObject 核心方法UiObject的常用方法与语义uiautomator2/_selector.py#L110-L578obj d(text登录) obj.exists # 元素是否存在property obj.count / len(obj) # 匹配数量 obj[0], obj[1] # 按 instance 取第 N 个支持负索引 obj.info # 元素信息 dictbounds、clickable 等 obj.center() / obj.bounds() # 中心坐标 / (lx, ly, rx, ry) obj.click(timeoutNone, offset(0.5, 0.5)) # 等待出现后点击 obj.click_exists(timeout0) # 存在才点击返回 bool obj.click_gone(maxretry10, interval1.0) # 反复点击直到消失 obj.long_click(duration0.5, timeoutNone) obj.set_text(你好) / obj.get_text() / obj.clear_text() obj.wait(existsTrue, timeoutNone) # 等待出现wait(existsFalse) 即等待消失 obj.wait_gone(timeoutNone) obj.drag_to(x, y, duration0.5) obj.swipe(up, steps10) # 元素内滑动 obj.gesture(s1, s2, e1, e2, steps100) # 双指手势 obj.pinch_in(percent100, steps50) # 双指缩小 obj.scroll.vert.toEnd() / obj.scroll.horiz.to() # 链式滚动 API obj.child(text确认) / obj.sibling(classNameButton) obj.child_by_text(1) / obj.child_by_instance(0) obj.right(text下一页) # 按方位找最近元素left/right/up/downclick的执行逻辑与 Java 端 uiautomator 一致先must_wait等待元素出现超时抛UiObjectNotFoundError再取visibleBounds不可见时取bounds按offset计算坐标最后下发点击L134-L153。wait的 HTTP 超时会比等待时间额外多 10 秒http_wait timeout 10以容纳网络往返L296-L327。四、Session应用保活会话Session继承自Deviceuiautomator2/init.py#L1048-L1083用于启动应用并持续监视其存活状态s d.session(com.example.app) # attachFalse先 stop 再启动 s d.session(com.example.app, attachTrue) # 附加到已运行的应用 s.running() # 应用是否仍在前台进程 s.pid # 应用 pid s.restart() # stop start 并刷新 pid s.close() # 停止应用其机制是重写jsonrpc_call每次 jsonrpc 调用前先检查 pid 是否存活应用已退出则直接抛SessionBrokenError避免对死会话做无意义的 RPCL1064-L1067。由于继承自DeviceSession 支持with语句退出时自动close()with d.session(com.example.app) as s: s.app_wait(com.example.app) s.click(0.5, 0.5) # 此处自动执行 s.close()五、XPath 插件d.xpath 的完整能力api.rst文档化的uiautomator2.xpath.XPath对应 uiautomator2/xpath.py 中的字符串子类XPath(str)L115-L134。它把简写语法在构造时就展开为标准 XPath 1.0 表达式strict_xpathL75-L112简写展开结果含义//设置//*[text设置 or content-desc设置 or resource-id设置]三属性全等com.example:id/btn//*[resource-idcom.example:id/btn]仅匹配 resource-id^搜索//*[re:match(text,搜索) or re:match(content-desc,搜索) or re:match(resource-id,搜索)]正则匹配注意需加引号^搜索\.*%abc%//*[contains(text,abc) or contains(content-desc,abc)]包含abc%//*[starts-with(text,abc) or starts-with(content-desc,abc)]前缀匹配%abc基于substring的后缀匹配后缀匹配/path/...原样保留标准 XPath5.1 XPathSelector 查询与等待d.xpath(...)返回XPathSelectorL292-L526xp d.xpath(//确定) xp.get() # 等待出现并返回第一个 XMLElement超时抛 XPathElementNotFoundError xp.exists # bool xp.all() # 所有匹配元素 xp.get_text() # 第一个匹配元素的 text xp.set_text(hi) # 点击聚焦后输入 xp.click(timeoutNone) # 等待 点击 xp.click_exists() # 存在才点击返回 bool xp.wait(timeoutNone) # 轮询等待出现默认每 0.2s 检查一次 xp.wait_gone(timeoutNone) xp.scroll_to(//目标, directionDirection.FORWARD, max_swipes10) xp.fallback(some_func) # 元素找不到时执行回调 xp.child(//sub) # 子路径选择器支持集合运算组合a d.xpath(//A) d.xpath(//B)取交集|取并集__and__/__or__L322-L334。等待超时默认取d.wait_timeout兜底 20 秒。PageSource解析层L137-L158会把 dump 出来的 XML 中每个node标签重命名为class属性值如android.widget.TextView因此可以用类名做标签选择d.xpath(//TextView).all()查询统一通过 lxml 的root.xpath执行并注册了re:正则命名空间以支持re:match。5.2 XMLElement 元素操作el d.xpath(//按钮).get() el.click() / el.long_click() el.screenshot() # 截取元素区域 el.swipe(up, scale0.6) # 在元素内部滑动 el.scroll(directionDirection.FORWARD) # 滚动并判断是否还有更多内容 el.scroll_to(//下一页, max_swipes10) el.parent() / el.parent(//容器) # 父节点可按 XPath 过滤 el.center() / el.bounds / el.rect # (x,y) / (l,t,r,b) / (x,y,w,h) el.offset(0.5, 0.3) # 按宽高分比例取点 el.percent_bounds() # 百分比边界可用于分辨率无关的断言 el.text / el.attrib / el.info # 文本、原始属性、结构化信息info属性L720-L743会把checkable、checked等布尔属性转换为驼峰命名的 Python dict并补充className、childCount、bounds子结构便于做断言。5.3 配套watcher 与 xpath 的取舍XPathEntry上保留了when()/run_watchers()/watch_background()等旧接口均已标记deprecated并指向d.watcherL200-L229新代码应使用d.watcher.when(...)注册监控规则。六、Settings影响行为的默认参数d.settings返回Settings对象uiautomator2/settings.py赋值时做类型校验合法键及默认值L15-L22d.settings[wait_timeout] 10 # 元素等待超时默认 20.0sUiObject.wait 与 XPath 轮询都受它影响 d.settings[operation_delay] (0.1, 0.1) # 操作前后延时单值会被扩成 (v, v)默认 (0, 0) d.settings[operation_delay_methods] # 参与延时控制的方法列表默认 [click, swipe] d.settings[max_depth] 50 # dump_hierarchy 的最大深度默认 50 d.settings[xpath_debug] True # XPath 调试默认 False d.settings[fallback_to_blank_screenshot] # 截图降级开关默认 False_operation_delay上下文L344-L357会在click、swipe等指定方法前后插入time.sleep用于规避部分设备上的触控抖动问题。此外implicitly_wait(seconds)是wait_timeout的旧式写法L306-L319源码 docstring 中已建议改用d.settings[wait_timeout]。七、小结uiautomator2 的 API 体系可以浓缩为一条调用链u2.connect()得到Device→d(text...)/d.xpath(...)得到元素对象 →click/set_text/wait完成交互d.session(pkg)则在其上叠加应用存活监视。三者分别由 uiautomator2/init.py、uiautomator2/_selector.py、uiautomator2/xpath.py 实现默认行为等待 20s、层级深度 50、百分比坐标等集中在 uiautomator2/settings.py。仓库中的测试用例tests/ 目录如 tests/test_xpath.py与 examples/ 下的示例脚本可作为进一步练习的起点。需要说明的是以上接口签名与默认值均取自当前仓库源码实际行为还受设备端 uiautomator-server APK 版本约束当前源码声明的 APK 版本为 2.4.0见 uiautomator2/version.py。赞分享测试移动开发GUI 自动化【免费下载链接】uiautomator2Android Uiautomator2 Python Wrapper项目地址https://gitcode.com/gh_mirrors/ui/uiautomator2点击查看免费下载相关推荐WSL Container API C 核心类详解Session、Container 与 Process 完整使用指南WSL Container API C 核心类详解Session、Container 与 Process 完整使用指南 导读 本文围绕 WSL 开源仓库中 C操作系统虚拟化系统编程网络iron-session核心API详解getIronSession、sealData和unsealData的完整使用教程iron session核心API详解getIronSession、sealData和unsealData的完整使用教程 iron session 是一个安全Picongpu终极指南如何在百亿亿次时代实现高性能粒子模拟Picongpu终极指南如何在百亿亿次时代实现高性能粒子模拟 Picongpu是一款面向百亿亿次计算时代的高性能粒子模拟框架专为实现性能可移植的粒子模拟而设上一篇3D VR 视频转 2D 免费方案用 VR-Reversal 在普通电脑上一步步玩转全景视频下一篇零门槛搞定照片批量水印semi-utils 让每张照片自动盖章创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考