用途
该技能用于规划和排序一次大型 XML-to-Compose 迁移,而不是提供逐屏转换的代码写法。它解决的核心问题是:大型迁移不是 N 个彼此独立的屏幕转换,而存在一条关键路径,最重要的排序决策在第一周就已做出。技能给出的结论是“最难屏幕优先”:最难屏幕会在预算尚存时暴露架构阻塞点;最易优先看似安全、能持续数月展示进度,但会在剩余时间最少时同时撞上所有阻塞。
主要能力与核心观点
- 先难后易:最难屏幕先行,尽早暴露架构层面的阻塞,留出解决预算。
- 状态收敛是重头:控件替换只占较小一半,较大一半是把旧屏幕散落在宿主类、适配器与监听器中的状态,收敛为声明式 UI 可读取的单一状态持有者;记录案例中最大非 UI 文件即共享状态持有者。
- 删除要等导航迁移:屏幕可以在新工具包中渲染很久,但旧宿主类、布局与导航条目仍然存在,因为旧导航图仍持有屏幕身份;在导航迁移提交之前,所有存活宿主类都无法删除。
- 导航是独立迁移:导航迁移有独立依赖,在类型安全导航模型下还会牵动序列化迁移,每个目的地变成可序列化类型,参数传递需在所有调用点重写;应作为单独发布项排期,并预期依赖目录同步变动。
- 进度应按删除的旧产物统计:仅统计“已迁移屏幕数”会失真,一个屏幕完全在新工具包中渲染时,其旧宿主类、布局和导航条目可能仍然存在。应统计每个发布标签下被删除的布局文件数。
- 避免中途做横切迁移:依赖容器替换、从可观察持有者迁移到 state flows 都属于横切改动,应落在 UI 阶段之前或之后。
- 状态分散的屏幕应等待:若屏幕数据经多个回调修改字段,先转换 UI 会把状态收敛写两遍;应先收敛、再转换。
- 共享状态持有者会变大:收敛是正确第一步,但会产出很大的类;应把拆分规划为后续工作,而不是以此反对收敛。
- 尾部文件不免费:最后几个文件往往被结构性改动(导航迁移、旧模块删除)而非惰性拖住,可能跨多个发布才清完。
使用方式与验证命令
技能提供一组在待迁移仓库上运行的只读 git 命令,用于核实真实进度:
按发布标签统计残留布局文件,绘制删除进度曲线:
for t in $(git tag | sort -V); do
printf '%-14s %s\n' "$t" "$(git ls-tree -r --name-only "$t" | grep -c '/res/layout/.*\.xml$')"
done
曲线持平说明旧世界在屏幕转换期间被继续保留;上升说明在新增宿主,或上升发生在迁移开始之前,需先给两者定日期再解读。
定位导航提交并确认其实际落在哪个发布:
git log --all --no-merges --diff-filter=D --format='%h %ad %s' --date=short --name-only \
-- '*/res/navigation/*.xml' '*/res/layout/activity_*.xml'
git tag --contains <that-commit> | sort -V | head -1
通过条件:此处得到的标签应正是导航提交所解释的那一步曲线变化。若不是数量骤降的那个标签,则骤降来自屏幕转换,两个事件相互独立。
确认序列化迁移随导航一同发生:
NAV=$(git log --all --no-merges --format=%h --diff-filter=D -- '*/res/navigation/*.xml' | head -1)
git show --format='' "$NAV" -- '*.kt' | grep -cE '^\+.*Serializable'
找出已经只剩外壳的宿主类,以预判导航变更将删除什么:
git grep -l 'ComposeView' -- '*Fragment.kt'
git grep -l 'ComposeView' <migration-era-commit> -- '*Fragment.kt'
检查一次“屏幕迁移”提交的重量实际去了哪里,按新增与删除行数分别排序:
git show --numstat --format='' <screen-migration-commit> | sort -k1 -rn | head
宿主类改写为外壳时在新增与删除两侧都很大、净值接近零。
在选择下一个屏幕之前,先数一数修改其渲染状态的独立回调数量;超过两三个就先收敛、再转换。
适用场景
适用于正在进行或计划进行的大型 Android XML 迁移到 Jetpack Compose 项目,尤其是屏幕多、状态分散、导航图复杂、还涉及依赖容器替换和响应式状态迁移的工程。也可用于向团队解释为何进度曲线与“已转换屏幕数”不一致。
限制
资料未提供该技能的安装方式、平台支持范围、运行环境依赖或收费信息;相关事实暂未提供。文中经验与数据来自特定项目的历史记录,是否适用于其他项目需结合实际情况判断。