readme.md

hmos-ui-align

HarmonyOS-Android UI 自动对齐流水线。

它解决什么问题

以往对齐鸿蒙和安卓 UI 的流程需要:

  1. 人工把设备点到目标页面
  2. 手动跑 parse 脚本截图 + dump view tree
  3. 肉眼对比差异
  4. 手写改鸿蒙源码

每多一个页面/弹窗/tab,上述步骤都要重复一遍,非常费时。

本 skill 做了三件事:

  • 用智谱 GLM 驱动的 phone-agent 自动寻路(根据自然语言点到指定页面)
  • 自动采集 view tree + 截图(安卓走 adb、鸿蒙走 hdc)
  • 自动对比 + 改码,并按 MVVM 模式把 mock 数据放到 Model 层

用户只需要一句自然语言 + 点击路径。

⚠️ 当前只保证 UI 对齐,不保证功能行为对齐。


前置条件

  1. 设备连接

    • 安卓设备:已装目标 App,adb devices 能看到
    • 鸿蒙设备:已装目标 App,hdc list targets 能看到
    • 两台设备建议都保持亮屏解锁
  2. Python 依赖

    pip install openpyxl phone-agent
    
  3. 智谱 GLM API Key(phone-agent 调用的模型) 到 https://open.bigmodel.cn/ 申请,有免费额度,填到 config.jsonglm_api_key

  4. 鸿蒙 SDK 路径(给改码阶段查 API 用) 例如 DevEco Studio 自带的 E:\DevEco Studio\sdk\default


配置 config.json

首次使用前必须改 Agents/hmos-ui-align/config.json。字段说明:

字段 说明 示例
android.app_name 安卓端 App 显示名(桌面上看到的名字,phone-agent 打开 app 时用) "Salt Player"
android.package 安卓包名 "com.salt.music"
android.project_dir 安卓源码根目录 "E:\\SaltPlayerAndroid-main\\SuvineMusicX"
harmony.app_name 鸿蒙端 App 显示名 "Salt Player"
harmony.package 鸿蒙包名 "com.xuncorp.sp2"
harmony.project_dir 鸿蒙工程根目录(会被直接修改) "E:\\SPH"
hmos_sdk_dir 鸿蒙 SDK 路径 "E:\\DevEco Studio\\sdk\\default"
glm_api_key 智谱 GLM API Key "xxx.yyy"
capture_output_dir 采集产物输出目录(截图/view tree/分析报告都在这) "./tmp_saltplayer"

可以直接参考同目录下的 config-example.json


使用方式

在 Claude Code 里直接调用 skill:

/hmos-ui-align <自然语言需求,描述要对齐的页面+点击路径>

写需求的三个要点

  1. 页面路径写清楚 用「→」或「-」标注一级一级的点击步骤,比如 首页 → 点击"AI智能填报" → 点击"专业"筛选按钮。路径越具体,phone-agent 寻路成功率越高。

  2. 说明是否要覆盖交互态 默认会自动扫描 tab、弹窗、下拉等交互元素并逐个采集。如果只想对齐主页面,请明确说「只对齐主页面,不管弹窗和 tab」。

  3. 说明是否用 Mock 数据 默认用 mock 数据。如果想调真实后台,在需求里写「不要 mock 数据,调用真实后台」。

例子

例 1(单个弹窗对齐)

/hmos-ui-align 鸿蒙版本app(登录状态下,进入首页-点击"AI智能填报"-点击"专业"筛选按钮)
得到的弹窗样式和安卓同样路径得到的页面不一致,请修改鸿蒙源码将上述页面与安卓版本完全对齐

例 2(补齐缺失页面 + 调真实后台)

/hmos-ui-align 鸿蒙版本app(点击我的-超级会员组件)显示与安卓不一致,且安卓版本在超级会员
上点击"会员中心"会跳到超级会员弹窗页,鸿蒙也没有这页。请修改鸿蒙源码将这些页面与安卓版本
完全对齐,不要mock数据,调用真实后台数据

例 3(多级路径 + 多个页面)

/hmos-ui-align 鸿蒙版本(点击底部高考按钮 -> 带年纪查专业 -> 点击某一具体专业(如临床医学)
-> 点击就业分析,到达"专业就业健康度"展示页面)以及在"专业就业健康度"页面上点击"完整数
据指标"到达的就业健康度详情页都和安卓同一路径的不一致。比较这些页面的差别并将他们在视觉
效果上完全对齐,不要用mock数据,调用后台真实逻辑

运行过程中会发生什么

skill 会严格按 SKILL.md 里的 5 步流水线跑:

Step 0 · 加载 config

config.json,解析出所有路径和 API Key。

Step 1 · 双端页面采集

1.1 解析你的需求,拆成一组「基础页」,每个基础页有 android_nav_pathhmos_nav_path 1.2 对每个基础页,两端分别:phone-agent 寻路 → 成功后 page_capture.py 截图 + dump view tree 1.3 扫描基础页 view tree,发现 tab、弹窗、下拉等交互元素,自动对每个子状态再采集一遍 1.4 鸿蒙端页面不存在时,寻路会失败,对应目录留空(Step 2 会改从源码读)

产物目录结构:

{capture_output_dir}/
  task_{timestamp}/
    android_page_1_{name}/
      screenshot.png
      view_tree.xml
    hmos_page_1_{name}/
      screenshot.png
      view_tree.xml
    android_page_1_{name}_popup_filter/
      ...

Step 2 · UI 差异分析

主 agent 串行执行,不会下放给子 agent(保证质量):

  • 2.1 读安卓 screenshot + view tree,写 android_page_*/UI_Analysis.md(组件清单 + 位置 / 颜色 / icon / 尺寸 / 对齐方式等)
  • 2.2 读鸿蒙 screenshot + view tree,写 hmos_page_*/UI_Analysis.md;鸿蒙页不存在时改读源码写 UI_Analysis_from_code.md
  • 2.3 两份 Analysis 对比,按 references/Comparison_Template.md 生成 UI_comparison.md(markdown diff 表)
  • 2.4 验证所有 UI_Analysis*.mdUI_comparison.md 都已写全

所有尺寸都会以 126px (3x → 42vp) 的格式同时给出原始 px、设备密度、换算后的 vp。

Step 3 · 改鸿蒙源码

  • 把每个 UI_comparison.md 里的 diff 项汇总到 {task_dir}/fix_checklist.md(唯一 source of truth)
  • references/MVVM开发文档/ 学习 MVVM 模式
  • page_align.md 学习转换规则
  • 逐条修 diff,每修一个把 - [ ] 改成 - [x]
  • 每个尺寸 / icon / alignment 都要回溯到安卓源码的 XML 或资源值,不允许"看起来差不多"

Step 4 · 编译校验

若可用,调 hmos-fix-build-errors skill 确保工程能编过。不会自动部署


目录结构

Agents/hmos-ui-align/
├── SKILL.md                    # 流水线定义(主 agent 执行逻辑)
├── readme.md                   # 本文档
├── config.json                 # 用户配置
├── config-example.json         # 配置样例
├── page_align.md               # Step 3 的转换规则
├── diff_analysis.md            # 内部说明
├── scripts/
│   ├── app_feature_verify.py   # phone-agent 寻路工具
│   ├── page_capture.py         # view tree + 截图采集工具
│   └── navigation-capure.md    # 两个脚本的调用约定
└── references/
    ├── UI_Analysis_Template.md                # Step 2 分析模板
    ├── Comparison_Template.md                 # Step 2.3 对比模板
    ├── MVVM开发文档/                           # 鸿蒙 MVVM 参考
    ├── android-to-harmonyOS-ui-layout-mapping-reference.md
    ├── android-to-harmonyOS-ui-atomic-component-mapping-reference.md
    └── android-to-harmonyOS-ui-interaction-mapping-reference.md

单独运行脚本(调试用)

跳过 skill 手动跑采集:

# 安卓寻路
$env:PYTHONIOENCODING="utf-8"
python Agents/hmos-ui-align/scripts/app_feature_verify.py `
  --device adb `
  --app "Salt Player" `
  --package "com.salt.music" `
  --prompt "进入首页-点击AI智能填报-点击专业筛选按钮" `
  --api-key "$env:GLM_API_KEY" `
  --max-steps 15

# 安卓采集
python Agents/hmos-ui-align/scripts/page_capture.py --device adb -o ./tmp/android_page_1_xxx

# 鸿蒙同理,把 --device adb 换成 --device hdc

注意:--prompt 模式会自动在前面加「打开{app_name},」,所以 prompt 里不要再写"打开"。


常见问题

Q: phone-agent 寻路失败怎么办? A: skill 默认重试两次。流水线的内部规则:①先看页面是否存在;②路径错了就 force-stop 重试;③路径对但工具报错就让 agent 自己看截图判断是否到了。超过两次仍失败才会跳过该页。

Q: 鸿蒙端页面根本不存在,能新建吗? A: 可以。Step 2.2 会改从鸿蒙源码读,Step 3 会按安卓的实现规格新建 .ets 文件到 entry/src/main/ets/pages/,并登记路由。

Q: 为什么同一次任务会采集多个页面? A: Step 1.3 默认扫描交互元素(tab / 弹窗 / 展开收起等)并递归采集。想关掉请在需求里写「只对齐主页面」。

Q: 改完会自动部署吗? A: 不会。Step 4 只跑编译验证(如果 hmos-fix-build-errors skill 可用)。部署自己来。

Q: 能不能只做差异分析、不改码? A: 目前流水线是端到端的。如果只想要分析产物,跑完 Step 2 后手动中断即可,所有 UI_Analysis.mdUI_comparison.md 都会落盘在 {capture_output_dir}/task_{timestamp}/ 下。


已知限制

  • 只对齐 UI,不对齐功能/数据流
  • phone-agent 寻路依赖 GLM 模型对页面文本的识别,小字体或非标准控件可能识别不准
  • 双端设备的分辨率/密度差异会影响像素到 vp 的换算,流水线已显式带上 density,但同一个 Figma 规格下仍可能出现 ±1vp 偏差