资讯动态

PureLive Android 设备 UI 地图与无截图回归框架实战指南

发布时间:2026/10/15 2:01:19 来源:尧图企业网站定制
音视频直播移动开发【免费下载链接】pure_live纯粹直播:哔哩哔哩/虎牙/斗鱼/快手/抖音/网易cc/YY直播/Twitch直播/SOOP直播/M38自定义源应有尽有。项目地址https://gitcode.com/gh_mirrors/pur/pure_live点击查看免费下载本文以 tool/DEVICE_UI_MAP.md 为核心系统讲解 PureLive 仓库中基于 device_ui_map.json 的“无截图”Android UI 回归体系坐标与语义双层缓存、按分辨率与方向自动选型、ADB 驱动点击/滑动/多步流程以及配套的设备租约与冒烟脚本。读完本文你将掌握android_ui.ps1的完整命令用法、device_ui_map.json的字段语义以及如何在新增机型或布局调整后安全维护这套 UI 测试基线。一、设计目标无截图、可复现、防误点的 UI 回归PureLive 的 Android UI 回归工作流建立在一个朴素但有效的观察上UI 自动化最常见的失败不是点错坐标而是把坐标发给了错误的应用。因此 tool/android_ui.ps1 刻意回避了截图 图像识别 持续集成重放的传统路线改为持久化坐标把已实测过、可稳定识别的控件坐标写入device_ui_map.json测试运行时直接复用语义兜底对每个坐标点尽量记录 Flutter/UIAutomator 暴露的语义标签如“菜单”“设置”“原画”必要时用语义树重新解析后再点击前台守卫每次动作前通过dumpsys activity activities读取topResumedActivity确认com.mystyle.purelive确实在前台否则直接中止绝不把缓存坐标打到别的应用上。这一设计带来的直接收益是正常回归运行时不截屏、不跑图像识别既避免了 UIAutomator 在弹幕持续刷新的直播间里等不到 idle 帧的问题也把“失败才留证据”的成本降到最低。二、持久化基线device_ui_map.json 的顶层结构device_ui_map.json目前为schemaVersion: 2目标包名为com.mystyle.purelive默认 profile 为k90pro_portrait_1200x2608。顶层只有两类成员profiles按机型/方向/分辨率维护的完整控件地图与defaultProfile降级缩放基准。每个 profile 内部固定包含四个分区分区作用数据形态points可点击/可识别的 UI 控件点{ x, y, label, semantic?, bounds? }gestures命名滑动手势{ x1, y1, x2, y2, durationMs, label }sequences多步动作流程由tap/tapSemantic/assertSemantic/swipe/wait五种原子动作组成的数组screens屏幕快照目录语义节点清单非图片{ recordedAt, appVersion, versionCode, nodes: [...] }以保留的 PJZ110OnePlus 13竖屏 profile 为例首页平台栏的实测点形如home.bilibili_tab: { x: 430, y: 480, label: 首页平台栏哔哩哔哩, semantic: 哔哩哔哩, bounds: [249, 384, 618, 576] }字段约定值得展开说明x/y控件中心点的物理像素坐标以该 profile 声明分辨率如1440x3168为基准记录label面向维护者的中文可读描述如“首页状态已开播”“设置向下滚动两次后本地互动体验”semantic单个字符串或字符串数组。数组用于支持中英双语别名例如设置页的semantic: [播放器内核…, 播放器内核]、直播间音频开关的[切换到纯音频模式, 切换到视频模式]bounds可选项记录该控件的[left, top, right, bottom]实际命中区域供语义解析与面积排序使用。仅记录坐标而不带语义的点如live.show_controls、nav.slot1~slot4则只有x/y/label。gestures的例子PJZ110 竖屏如下包含完整的起终点与时长settings.scroll_down: { x1: 720, y1: 2680, x2: 720, y2: 760, durationMs: 420, label: 设置列表向下滚动一屏 }sequences则由若干“一步一动作”的步骤组成比如打开小窗弹幕设置页open_pip_danmaku_settings: [ { tapSemantic: [菜单, Menu], waitMs: 350 }, { tapSemantic: [设置, Settings], waitMs: 600 }, { tapSemantic: [小窗弹幕, PiP Danmaku], waitMs: 600 }, { assertSemantic: [样式预览, Style Preview] } ]注意最后一步是assertSemantic——只断言、不点击用于确认到达了目标页面。已录制的机型基线当前主测机型为K90 Pro序列号25102RKBEC代号myronAndroid 17通过网络 ADB 接入维护两套 profile竖屏1200 x 2608k90pro_portrait_1200x2608横屏2608 x 1200k90pro_landscape_2608x1200。其竖屏 profile 的notes字段明确记载K90 Pro 的首批坐标是从保留的 PJZ110 测量值按比例迁移而来因此任何点的首次“状态改变性使用”之前都必须先跑-Validate并优先-VerifySemantics在对应路由被物理验证后重新记录屏幕快照——避免把缩放坐标当成实测证据。仓库同时保留了 PJZ110OnePlus 13的实测 profile 作为归档回归基线竖屏1440 x 3168覆盖首页、开播/录播/未开播筛选、可见平台标签、房间卡片、侧边抽屉、完整设置列表、直播间顶栏、播放器控制、弹幕标签页、本地弹幕发送、底部导航与滚动手势横屏3168 x 1440覆盖直播间顶栏、视频区域、音频/投屏/小窗PiP控制、清晰度/线路控制与完整右侧弹幕面板稳定的屏幕目录首页、抽屉、设置页顶部/中部/底部与直播间基础态。一个重要的边界在文档中被反复强调动态房间标题与实时弹幕文本不视为稳定控件不应进入坐标地图。三、运行前置条件设备租约、唤醒与身份核对由于同一部 Android 实机被 BiliRoaming、小红书Xiaohongshu与 PureLive 三个任务按固定biliroaming - xhs - purelive轮转共享任何会改变实机状态的操作都必须先通过 tool/run_android_device_test_turn.ps1 获取purelivelane 的设备轮次turn具体规则见 docs/ANDROID_DEVICE_TEST_ROTATION.md。典型调用.\tool\run_android_device_test_turn.ps1 -CommandLine .\tool\android_ui.ps1 -Validaterun_android_device_test_turn.ps1内部会向仓库上级目录寻找共享协调器shared-device-test-rotation\Invoke-DeviceTestTurn.ps1调用 tool/wake_android_device.ps1 执行唤醒与“常亮”租约StayAwake并在命令结束后只对成功获取常亮的目标恢复原始设置随后把PURELIVE_ADB_SERIAL注入环境后执行测试正文。它支持-Pass本轮无设备工作直接交棒、-NoRotation跳过轮转协调但保留唤醒、前台校验与失败清理与显式-Serial IP:PORT。文档还强调了三条硬性边界同一无线设备同时暴露 mDNS 别名时必须传精确的 IP 串号如192.168.1.2:5555配对端口与配对码是临时的严禁写入仓库UI 回归工作流不要求 root也绝不从设备侧管理器应用推断 root 能力。拿到轮次之后android_ui.ps1自身仍会执行强制的前台包守卫先Wake-AndDismissKeyguard处理锁屏K90 Pro 配置为十分钟自动锁屏脚本会读取dumpsys window policy判断是否仍锁定必要时按屏幕比例滑动解锁再通过am start -W拉起应用并轮询观察topResumedActivity迁移最多 12 次、每次 250 ms而不是依赖固定延时——因为 Flutter 冷启动时 ActivityManager 可能先返回桌面。四、命令速查android_ui.ps1 全参数详解android_ui.ps1使用 PowerShell 参数集ParameterSet区分动作-Serial默认取$env:ANDROID_SERIAL。完整命令清单如下。校验与罗列# 校验 JSON 引用完整性并列出当前 profile 的全部点/手势/序列/快照 .\tool\android_ui.ps1 -Validate .\tool\android_ui.ps1 -List-Validate对应脚本中的Test-Map检查每个点的坐标是否越出 profile 边界、每个序列步骤是否恰好声明一个动作、tap引用的点与swipe引用的手势是否存在、语义动作是否为空、wait动作是否携带合法waitMs最后再整体ConvertFrom-Json复验可解析性。预览或执行缓存动作流程.\tool\android_ui.ps1 -Sequence toggle_audio -DryRun .\tool\android_ui.ps1 -Sequence toggle_audio # 从首页直达常测设置页 .\tool\android_ui.ps1 -Sequence open_pip_danmaku_settings .\tool\android_ui.ps1 -Sequence open_local_interaction_settings .\tool\android_ui.ps1 -Sequence open_general_settings-DryRun只打印将要执行的每一步含坐标与来源不真正下发 ADB 命令去掉后按序执行tap/tapSemantic/assertSemantic/swipe/wait五种动作每一步的waitMs在动作之后生效。语义解析、复核与坐标维护# 从无障碍语义树解析一个可见控件并点击不截屏 .\tool\android_ui.ps1 -TapSemantic 关闭菜单 # 点击前先用当前语义树复核缓存坐标 .\tool\android_ui.ps1 -Tap live.audio_toggle -VerifySemantics # 记录/修正一个坐标点后续测试直接复用 .\tool\android_ui.ps1 -Record settings.example -X 1200 -Y 900 -Label 设置示例入口 # 将当前路由上所有稳定可操作控件存入屏幕目录 .\tool\android_ui.ps1 -Snapshot settings.example .\tool\android_ui.ps1 -RemoveSnapshot settings.example # 仅在请求动作失败时保存截图与 XML 证据 .\tool\android_ui.ps1 -Sequence toggle_audio -CaptureOnFailure参数细节-TapSemantic只走语义树命中Find-SemanticNode后点击节点中心候选可传多个脚本用Format-SemanticCandidates输出A or B找不到即报错。-VerifySemantics仅对tap生效——先Get-UiNodes拉语义树若能按该点的semantic候选命中节点则使用节点中心坐标来源标记为semantic否则回退到缓存坐标来源cache。-Record按“当前实测分辨率 → profile 基准分辨率”的比例把(X, Y)换算为基准坐标后写入对应 profile 的points坐标换算逻辑见脚本Record分支。-Snapshot调用 UIAutomator 拉取当前 UI 层级uiautomator dump --compressed把**所有有身份标识text/描述/resource-id 任一非空且可操作clickable/long-clickable/scrollable/checkable**的节点连同 bounds、center、状态位写入该 profile 的screens默认跳过***:形式的密码语义。快照同时记录appVersion、versionCode、orientation与topPackage用于追溯。-CaptureOnFailure动作抛错时Save-FailureEvidence会在.dart_tool\device-ui-failures下按yyyyMMdd-HHmmss-动作.png/.xml保存screencap与 UIAutomator XML。自动隐藏控件与“两步点击”快速路径播放器控制栏这类自动隐藏控件在缓存地图中采用两步流程先点live.show_controls唤出控制层等待 700 ms再点目标控件。toggle_audio序列正是如此toggle_audio: [ { wait: true, waitMs: 2600 }, { tap: live.show_controls, waitMs: 300 }, { tap: live.audio_toggle, waitMs: 0 } ]文档特别说明这条快速路径刻意跳过 UI 层级 dump因为层级转储可能比自动隐藏的控制层存活时间还长反而引入不稳定。五、竖屏全屏手势v3.0.22 的两个命名序列PureLive v3.0.22 引入竖屏直播全屏展示后UI 地图补充了两个可复用的手势序列。它们只能在已验证坐标的设备上、进入稳定识别的竖屏直播间后使用.\tool\android_ui.ps1 -Sequence enter_portrait_fullscreen .\tool\android_ui.ps1 -Sequence restore_portrait_panelenter_portrait_fullscreen从竖屏弹幕面板的手柄区live.portrait_sheet_handleK90 Pro 竖屏坐标为(600, 1646)语义标签“下滑进入竖屏全屏”向下滑动进入沉浸展示restore_portrait_panel从屏幕底部K90 Pro 竖屏为live.portrait_fullscreen_restore_zone即(600, 2527)向上滑动恢复弹幕栏。在device_ui_map.json中它们对应的手势定义以 K90 Pro 竖屏 profile 为准为live.portrait_fullscreen_down: { x1: 600, y1: 1646, x2: 600, y2: 2511, durationMs: 650, label: 竖屏直播弹幕面板下滑进入竖屏全屏 }, live.portrait_fullscreen_up: { x1: 600, y1: 2438, x2: 600, y2: 1904, durationMs: 420, label: 竖屏全屏提示条上滑恢复弹幕栏避开系统底部手势区 }两个序列本身“只记录确定坐标与等待时间”。文档明确划定了边界直播源是否为稳定竖屏仍由 PureLive 应用自身状态机判定脚本不会强制普通直播进入该模式。六、深层原理坐标选型、缩放与语义解析自动选型与降级缩放Resolve-Profile的优先级是显式-Profile参数 → 按当前dumpsys window displays或wm size读取的实际分辨率 方向精确匹配 → 回退到defaultProfile并按比例缩放。回退前会先检查默认 profile 的方向是否与当前一致方向不一致时直接报错绝不盲目套用——这对应维护规则第 1 条“竖屏坐标不得盲目搬到横屏”。缩放公式为见Resolve-Pointx round(point.x / profile.width * 当前屏宽) y round(point.y / profile.height * 当前屏高)swipe手势的起终点同样按此比例换算durationMs缺省时默认 350 ms。语义树解析的工程细节Get-UiNodes有若干值得借鉴的实现要点使用shell timeout 10 uiautomator dump --compressed限定转储时间上限——直播间弹幕持续变化UIAutomator 可能永远等不到 idle 帧Android 内置超时防止整个回归被卡死转储文件通过adb pull以字节流方式读取并显式按 UTF-8 解码——因为 Windows PowerShell 5.1 若用adb shell cat捕获输出会按活动 OEM 代码页解码导致中文语义标签损坏Find-SemanticNode按候选语义逐条匹配节点的content-desc或text支持描述\n...前缀形式并按“可点击优先、命中面积小者优先”排序取第一个。语义断言防止“假成功”对路由敏感的序列文档要求使用双语tapSemantic候选 末尾assertSemantic。assertSemantic读取目标页的无障碍树若找不到预期的“仅该页面存在”的标签例如打开播放器内核设置后断言“核心内核设置 / Core Kernel Settings”打开小窗弹幕设置后断言“样式预览 / Style Preview”序列就以错误终止——从而保证过期的坐标或未变化的屏幕永远不会被报告为一次成功的路由。播放器状态的验证边界文档维护规则第 5 条是一条重要纪律每次动作后要通过应用日志/语义树验证播放器状态一次成功的点击本身不等于一次成功的播放结果。坐标地图只管“点到”播放是否生效由专门的冒烟脚本见下文负责闭环验证。七、配套冒烟脚本PiP 弹幕设置验证示例android_ui.ps1是底层驱动上层业务验证由各冒烟脚本组合完成。文档给出的示例是在已获取的设备轮次内验证 PiP 预览的开启/关闭与持久化.\tool\android_pip_danmaku_settings_smoke.ps1 -Serial 192.168.1.2:5555 -EvidenceDirectory local-artifacts/diagnostics/pip-danmaku-settings从源码看tool/android_pip_danmaku_settings_smoke.ps1 的验证纪律包括必传-Serial且先校验目标身份——getprop ro.product.model必须等于25102RKBEC、ro.product.device必须等于myron身份不符直接中止见Get-Identity证据目录统一落在local-artifacts/diagnostics/场景名场景开始/结束时都会uiautomator dump与screencap双通道采集 UI 状态并在finally中清理设备侧临时文件文档进一步说明该脚本会在验证后恢复精确的规范 Hive 文件并停止应用确保测试不污染后续轮次。八、维护规则与回归纪律DEVICE_UI_MAP.md的维护规则是整条工作流的“宪法”逐条落地如下竖屏/横屏 profile 严格分离绝不盲目旋转竖屏坐标——选型与缩放逻辑已在第六节说明Flutter 暴露语义标签时就记录但保留实测坐标用于快速执行——坐标是主路径语义是兜底与复核二者缺一不可滚动相关点位加_after_scroll2之类的后缀并把所需滑动编码进命名序列——例如settings.network_proxy_after_scroll1、settings.general_after_scroll2、settings.backup_after_scroll2对应序列open_local_interaction_settings连续两次settings.scroll_down后再tapSemantic 本地互动体验布局变更后刷新受影响的屏幕快照实机回归前先跑-Validate每次动作后通过应用日志/语义验证播放器状态成功点击不等于播放结果导航序列在存在稳定标签时以目标页专属assertSemantic收尾并为本地化路由提供中英双语别名。结合源码还可以补充一条工具链纪律-Record/-Snapshot写回device_ui_map.json时Save-Map会先ConvertTo-Json -Compress再用脚本内自实现的Format-JsonText重排为缩进 JSON并以无 BOM 的 UTF-8落盘——同样是为了避开 Windows PowerShell 5.1 对无 BOM UTF-8 文件的 ANSI 误读问题快照节点过滤表达式中也保留了“仅 ASCII”的注释约束。九、从零接入一台新机型的操作路径结合上文全部机制将一台新 Android 机型接入这套回归体系的标准流程是接入并核对身份网络 ADB 连接后显式指定-Serial IP:PORT先用只读命令核对ro.product.model/ro.product.device确认不是按设备列表顺序猜测目标获取设备轮次通过 tool/run_android_device_test_turn.ps1 进入purelivelane建立 profile 骨架在device_ui_map.json的profiles中新增竖屏与横屏两个 profile声明分辨率与方向迁移或实测坐标可参考既有机型按比例迁移首批坐标但必须随后逐点用-VerifySemantics/-TapSemantic物理复核状态改变性动作首次使用前先-Validate用-Record修正偏差、用-Snapshot记录屏幕目录把复核过的点固化为缓存基线验证关键序列依次跑open_settings、open_pip_danmaku_settings、toggle_audio、enter_portrait_fullscreen/restore_portrait_panel竖屏直播场景等命名序列确认带assertSemantic的序列能在目标页正确收尾纳入轮转在正常轮次中以-Validate开头、以带-CaptureOnFailure的业务序列结束将新机型正式纳入每日回归。整个过程从缓存坐标、语义兜底、前台守卫到失败取证都无需截图与图像识别这正是 PureLive 这套“UI 地图 ADB 驱动”方案在弹幕密集型直播应用中保持稳定与快速的关键所在。十、相关资源索引入口文档tool/DEVICE_UI_MAP.md核心驱动脚本tool/android_ui.ps1UI 坐标/手势/序列/快照数据库tool/device_ui_map.json设备轮次包装器tool/run_android_device_test_turn.ps1 与共享实机轮转规则 docs/ANDROID_DEVICE_TEST_ROTATION.md设备唤醒/常亮租约tool/wake_android_device.ps1上层业务冒烟示例tool/android_pip_danmaku_settings_smoke.ps1实测回归基线文档docs/ANDROID_DEVICE_REGRESSION_2026_08_28.md、docs/ANDROID_RUNTIME_AUDIT_3_1_8_K90PRO.md赞分享音视频直播移动开发【免费下载链接】pure_live纯粹直播:哔哩哔哩/虎牙/斗鱼/快手/抖音/网易cc/YY直播/Twitch直播/SOOP直播/M38自定义源应有尽有。项目地址https://gitcode.com/gh_mirrors/pur/pure_live点击查看免费下载相关推荐Folcolor编译指南使用Visual Studio 2022构建完整项目Folcolor编译指南使用Visual Studio 2022构建完整项目 Folcolor 是一款出色的Windows文件夹着色工具它能帮助您通过颜色快桌面应用开发工具Front-End-Checklist 视觉回归测试实战用 Playwright 截图对比拦截 CSS 回归Front End Checklist 视觉回归测试实战用 Playwright 截图对比拦截 CSS 回归 视觉回归测试Visual Regressionfastlane frame_screenshots(frameit)实战指南用 Framefile.json 为 iOS/macOS/Android 截图批量套上设备边框fastlane frame_screenshots frameit 实战指南用 Framefile.json 为 iOS/macOS/Android 截图批开发工具CI/CD移动开发上一篇Fleet命令行工具详解fleetctl常用操作与高级技巧下一篇Dioxus Desktop 桌面渲染器深入解析用 WebView 构建跨平台原生桌面应用创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑