3、顶层模块边界定义:基于功能域划分核心组件与共享基础层

SystemUI 的组件化拆分首先需要回答一个问题:“软件单元应该按什么维度切分?” 本章遵循功能域驱动原则,将用户可感知的独立交互区域或后台功能模块作为一级拆分单元,同时提取所有组件共同依赖的资源、工具与抽象层作为共享基础层。这种划分方式保证了高内聚、低耦合,使每个组件可以独立开发、测试和部署。

3.1 核心组件清单与职责边界

以下五个核心组件直接映射为 Android 系统 UI 的可见实体,它们之间的边界由交互区域不重叠、数据源不耦合的原则确定。

组件名称功能职责主要输入(事件/数据)对外输出依赖共享基础层
状态栏(StatusBar)显示系统状态图标、时间、电池、信号;处理轻触展开通知面板系统广播(时间、电量、信号强度)展开手势信号;图标布局快照资源加载、图标绘制、动画模块
导航栏(NavigationBar)呈现三键(返回/主页/最近任务)或手势指示器;处理按键事件触摸事件、系统手势模式变更按键事件分发、手势区域坐标触控反馈、窗口布局策略
通知面板(NotificationPanel)展示通知列表、分组折叠、快捷回复;可展开/折叠通知管理器推送、用户滑动事件通知操作结果、面板展开状态通知数据模型、列表适配器、阴影渲染
锁屏(Keyguard)锁定屏幕时的交互界面:解锁、紧急呼叫、时钟、通知概览锁屏状态、指纹/人脸识别结果、用户输入解锁信号、安全事件通知生物识别集成、屏幕管理策略、动画过渡
快捷设置(QuickSettings)提供 Wi-Fi、蓝牙、亮度、旋转等快捷开关;可编辑排序系统设置变更、用户点击/长按设置变更请求、面板关闭信号开关图标库、共享偏好存取、动画轨道
边界校验准则:若某个功能的修改需要同时改动两个组件才能完成,说明功能域划分存在重叠。例如,“显示通知数量”在状态栏和通知面板中各有涉及,此时应将数量聚合逻辑下放到共享基础层,保持两个组件仅依赖同一个数据模型。

3.2 共享基础层:组件的“地基”

共享基础层不包含任何业务逻辑,它提供所有组件都需要的通用能力,避免重复实现。主要包含四大子领域:

  • 资源与主题管理:颜色、字体、尺寸、Dimens、Drawable、字符串统一由基础层加载并提供给组件。
  • 公共 UI 工具库:复用组件(如圆形图标、进度条、可拖拽面板)、动画插值器、阴影生成器、触摸事件拦截器。
  • 数据模型与协议:通知模型、系统状态枚举、广播事件契约(如 Intent action 常量)、接口定义(如面板展开监听器)。
  • 跨进程通信抽象:封装 Binder 调用、SystemUI 内部的服务代理,使组件无需直接处理 IBinder。

共享基础层的引入使组件间的通信不再直接依赖,而是通过接口 + 事件总线的方式间接完成。例如,状态栏需要知道锁屏是否激活——它不会直接调用锁屏对象的方法,而是通过基础层的 KeyguardStateProvider 观察状态变化。

3.3 组件间的数据流与控制流

即使基于功能域划分,组件之间仍存在必要的协作。我们将其归纳为三种典型流向:

  1. 垂直数据流:共享基础层向下游组件推送系统状态(时间、电量、通知数)。
  2. 水平控制流:组件间通过事件总线发出指令。例如,“快捷设置”点击“飞行模式”开关后,通过总线通知“状态栏”更新图标;“通知面板”折叠时通知“状态栏”恢复成全透明背景。
  3. 跨场景重定向:锁屏下的通知点击需要先验证身份,此时锁屏组件接管控制权,待解锁完成后将事件转发给通知面板。

采用事件总线而不是直接方法调用的核心原因:降低编译时依赖,允许组件以动态插件形式加载,为后续的按需加载和热修复提供基础。

3.4 选型权衡与风险点

  • 粒度权衡:将通知面板拆分为“列表区”和“折叠区”是否值得?在初期保持粗粒度划分,等性能瓶颈出现后再进行二级拆分更稳妥。
  • 数据冗余风险:多个组件同时持有同一份状态缓存(如蓝牙开关状态),可能导致不同步。解决方案:让共享基础层提供单一的 StateHolder,组件只读不写。
  • 事件总线膨胀:随着组件增多,事件类型可能爆炸。建议使用领域事件分组(如 Event.System、Event.Notification、Event.Input),保持可搜索性。
  • 锁屏优先级:锁屏组件拥有最高渲染优先级,但它不能阻塞其他组件的后台事件处理。应确保锁屏组件与状态栏、通知面板的线程模型隔离。

3.5 落地步骤与验收标准

三步落地方案:

  1. 阶段一(1~2周):代码移动与接口提取。将现有 SystemUI 代码按功能域搬移到新包路径下,同时将公共资源、工具类、数据模型抽成独立的 shared 模块。
  2. 阶段二(2~3周):事件总线接入与依赖反转。移除组件间的直接 import,改为事件发布/订阅;通过测试验证所有交互场景与原实现一致。
  3. 阶段三(1周):独立编译与验证。每个组件可以单独编译成 APK 或动态特性模块,运行在 Android Studio 的 systemui:component:run 任务下。

验收标准清单:

  • 每个核心组件不直接引用其他组件的 Java/Kotlin 类(接口引用允许)。
  • 所有资源引用通过 R.shared.* 或 R.component.* 区分,无混合使用。
  • 运行 Monkey 测试 8 小时,无因组件间通信导致的 ANR 或 Crash。
  • 修改一个组件的图标样式不影响其他组件的布局。
常见陷阱:切忌在共享基础层中放置“看起来通用但实际上只被一个组件使用”的代码。这类代码应留在原组件中,待第二个消费者出现时再上提。否则基础层会迅速退化为“垃圾场”,破坏架构整洁性。
SystemUI 顶层模块边界划分(功能域视角) 共享基础层(Shared Foundation) 资源加载|公共UI工具|数据模型|事件总线|Binder封装 状态栏 StatusBar 导航栏 NavigationBar 通知面板 NotificationPanel 锁屏 Keyguard 快捷设置 QuickSettings 手势切换 折叠通知 组件边界规则 功能域不重叠 共享基础层统一依赖 事件总线 水平控制流 间接通信