GONE View ViewStub 化技术方案(N801PROB-126046 第一波#7)
来源:N801PROB-126046 Settings 冷启动 review 第一波优化项 #7
Trace 证据:首帧 inflate 143ms 中,3 个 GONE micarx Toolbar 完整构造 11.44ms、GONE ProgressBar 3.30ms、GONE cl_anchor_jump ~2ms,连带 ~18 个 VectorDrawable 解析 11.31ms —— 合计 ~17-28ms 的纯浪费(不可见 View 在首帧完整 inflate)
影响范围:app(car_setting_activity.xml)+ base/settingsBaseUi(car_ui_preference_fragment_auto.xml),全变体生效
一、目标与风险审计结论
| 目标 | 布局 | 首帧可见? | 代码引用 | 审计结论 |
|---|
dialog_activity_page_toolbar | car_setting_activity | 从不(GONE,零代码引用) | 无 | ✅ 纯死重,仅作 layout_below 锚点 |
toolbar(activity) | car_setting_activity | 首页不显示 | BaseCarSettingsActivity 3 处,全部判空;仅 setTitle() 时 VISIBLE(仅 NotificationsFragment 链路) | ✅ setTitle 内按需 inflate |
mi_car_toolbar | car_ui_preference_fragment_auto | 首页不显示 | SecondLevelSettingsFragment(二级页 nav bar)、LocationSettingsFragment(globalOnly)、BaseXmlParserSettingsFragment.fitSystemBar(setMargin 已判空) | ⚠️ 二级页/位置页需先 inflate |
progressbar_frame | car_ui_preference_fragment_auto | 首页不显示 | SecondLevelSettingsFragment.installProgress + MiCarApplicationsSettingsFragment 显隐(未判空) | ⚠️ 二级页 installProgress 先 inflate |
cl_anchor_jump | car_ui_preference_fragment_auto | Modena 不显示 | TopLevelSettingsFragment.onViewCreated,仅 isAnchorAvailable()(Kunlun E4U4.2+)分支内使用(未判空) | ⚠️ 该分支内先 inflate |
统一模式:ViewStub android:inflatedId 保留原 id —— inflate 后 findViewById(原id) 照常工作;未 inflate 时返回 null(审计确认所有”首页路径”的引用点要么不存在、要么已判空)。
锚点兼容性:RelativeLayout layout_below / ConstraintLayout constraint 均可指向 ViewStub;GONE View 与未 inflate 的 ViewStub 在两套布局里都按 0 尺寸参与定位,锚点语义不变。
二、改动内容
2.1 新增 5 个拆分布局(原样搬迁,零修改)
| 新文件 | 内容 |
|---|
app/.../layout/micar_dialog_page_toolbar.xml | micarx Toolbar(style Overlay.MiCarX.Toolbar.Dialog) |
app/.../layout/micar_activity_toolbar.xml | micarx Toolbar(style Overlay.MiCarX.TitleCenter.Toolbar) |
settingsBaseUi/.../layout/micar_fragment_toolbar.xml | micarx Toolbar(style Overlay.MiCarX.Toolbar + titleCentered/titleTextAppearance) |
settingsBaseUi/.../layout/micar_progressbar_frame.xml | FrameLayout + ProgressBar(原样) |
settingsBaseUi/.../layout/micar_cl_anchor_jump.xml | ConstraintLayout + TextView + ImageView(原样,id 保留) |
2.2 原布局替换为 ViewStub
car_setting_activity.xml:dialog_activity_page_toolbar(ViewStub 沿用同 id)、toolbar → toolbar_stub(inflatedId=toolbar);ViewStub 继承原布局参数
car_ui_preference_fragment_auto.xml:mi_car_toolbar / progressbar_frame / cl_anchor_jump → 对应 *_stub,约束/边距原样搬到 ViewStub 上
2.3 代码侧 4 处按需 inflate(各 ≤4 行)
| 文件 | 位置 | 改动 |
|---|
BaseCarSettingsActivity.java | setTitle() | inflate toolbar_stub 后再走原逻辑 |
SecondLevelSettingsFragment.java | installNavBackTool() / installProgress() | 先 inflate 对应 stub 再 findViewById |
LocationSettingsFragment.java | setupToolbar() | 先 inflate mi_car_toolbar_stub |
TopLevelSettingsFragment.java | onViewCreated() 的 isAnchorAvailable 分支 | 先 inflate cl_anchor_jump_stub |
预期收益
- 首页(双栏)首帧:3 Toolbar 11.44ms + ProgressBar 3.30ms + anchor 2ms + 关联 VectorDrawable ~10ms ≈ 17-28ms
- 二级页/位置页/Kunlun 锚点页:按需 inflate,行为与今天一致(成本后置到真正需要时)
三、风险控制
| 风险 | 评估 | 对策 |
|---|
| 未 inflate 时 findViewById=null | 已审计:首页路径无未判空引用 | 二级页/锚点/位置页显式 inflate |
| ViewStub 布局参数丢失 | 中 | 原约束/边距全部搬到 ViewStub;装车对比二级页 toolbar 位置 |
| LocationSettingsFragment 属 globalOnly(XCD global) | 低 | 该模块同库编译,xcddif 不受影响 |
| 二级页首次进入多一次 inflate | 可忽略(~4ms,且不在冷启动路径) | — |
四、验证计划
:base:settingsBaseUi:assembleXcdDebug + :app:compileXcdDebugJavaWithJavac + manifest merge 通过
- 首页首帧像素对比(应一致,且无 GONE View 构造)
- 二级页(任意设置子页)toolbar 返回键/标题/右侧文字显示与位置正常
- 应用管理页 loading(progressbar_frame)显隐正常
- Kunlun 车型锚点跳转按钮(如可借机)显示正常;Modena 不显示
- perfetto 复测:首帧 inflate 应下降 ~17-28ms