Android7 SystemUI 源码解析(一)全景概览与架构设计

系列导航一:全景概览与架构设计 | 二:启动流程深度解析(本文) | 三:StatusBar 状态栏 | 四:NavigationBar 导航栏 | 五:通知系统 | 六:QuickSettings | 七:Keyguard 锁屏 | 八:Recents 与其他子系统


一、SystemUI 是什么

SystemUI 全称 System User Interface ,直译为"系统用户界面"。它是 Android 系统中承载系统级交互与状态展示 的核心组件,我们日常看到的状态栏、导航栏、通知中心、锁屏界面、快捷设置面板、最近任务列表等,都属于 SystemUI 的范畴。

从技术角度看,SystemUI 是一个系统级 APK ,源码位于 frameworks/base/packages/SystemUI/ 下。

注意它不是放在 packages/apps/ 下,而是放在 frameworks/base/packages/ 下,这意味着 SystemUI 本质上属于 Framework 层 ,拥有系统签名(android:sharedUserId="android.uid.system"),可以直接与 WindowManagerServiceActivityManagerServiceNotificationManagerService 等核心系统服务进行交互。

二、SystemUI 的核心职责

SystemUI 在 Android 系统中扮演着以下四个关键角色:

1. 状态呈现中心

实时展示系统关键状态信息:时间、电池电量、网络信号、Wi-Fi、蓝牙、闹钟、通知图标等。

2. 全局交互入口

提供用户与系统交互的关键通道:

  • 状态栏(StatusBar):下拉通知/快捷设置、显示状态图标
  • 导航栏(NavigationBar):返回、主页、最近任务(经典三键)
  • 锁屏(Keyguard):安全认证(PIN/图案/密码)、紧急呼叫、通知预览
  • 通知抽屉(NotificationPanel):集中管理所有应用通知
  • 快捷设置面板(QuickSettings):一键开关 Wi-Fi、蓝牙、飞行模式等

3. 安全边界守护者

在锁屏状态下充当安全屏障,控制对设备的访问,管理敏感通知的显示策略。

4. 沉浸式体验协调者

管理应用全屏模式下系统栏的显示与隐藏逻辑,处理 SYSTEM_UI_FLAG_FULLSCREENSYSTEM_UI_FLAG_HIDE_NAVIGATIONSYSTEM_UI_FLAG_IMMERSIVE_STICKY 等标志位。

三、源码目录结构总览

复制代码
frameworks/base/packages/SystemUI/
├── AndroidManifest.xml            # 应用清单(系统权限声明)
├── res/                           # 资源文件
│   ├── layout/                    # 布局文件(状态栏、导航栏、通知面板等)
│   ├── values/                    # 配置值
│   ├── drawable/                  # 图标资源
│   └── anim/                      # 动画资源
├── src/com/android/systemui/
│   ├── SystemUIService.java       # ★ 入口 Service
│   ├── SystemUIApplication.java   # ★ Application 类(定义 SERVICES 数组)
│   ├── SystemUI.java              # ★ 所有子模块的抽象基类
│   ├── SystemUIFactory.java       # 通过反射创建各子模块实例
│   ├── statusbar/                 # 状态栏 + 导航栏(SystemBars 在此)
│   │   ├── SystemBars.java        # ★ 状态栏/导航栏总控服务
│   │   ├── CommandQueue.java      # ★ 命令队列(与系统服务通信)
│   │   ├── BaseStatusBar.java     # 状态栏抽象基类
│   │   ├── phone/                 # 手机形态状态栏
│   │   │   ├── PhoneStatusBar.java        # ★ 状态栏核心
│   │   │   ├── NavigationBarView.java     # ★ 导航栏视图
│   │   │   ├── StatusBarWindowView.java
│   │   │   └── ...
│   │   └── policy/                # 按键策略
│   │       └── KeyButtonView.java
│   ├── keyguard/                  # 锁屏模块
│   │   ├── KeyguardViewMediator.java      # ★ 锁屏调度核心
│   │   └── ...
│   ├── tuner/                     # 开发者调试面板(TunerService)
│   ├── stackdivider/              # 分屏(Divider 在此)
│   │   └── Divider.java
│   ├── recents/                   # 最近任务模块
│   │   ├── Recents.java
│   │   └── RecentsActivity.java
│   ├── volume/                    # 音量控制模块
│   │   ├── VolumeUI.java
│   │   └── VolumeDialogController.java
│   ├── power/                     # 电源管理模块
│   │   └── PowerUI.java
│   ├── qs/                        # QuickSettings 快捷设置
│   │   ├── QSPanel.java
│   │   └── tiles/                 # 各种 Tile 实现
│   ├── media/                     # 铃声播放(RingtonePlayer)
│   ├── keyboard/                  # 键盘快捷键(KeyboardUI)
│   ├── shortcut/                  # 快捷键分发(ShortcutKeyDispatcher)
│   ├── tv/                        # TV 形态(tv.pip.PipUI)
│   └── usb/                       # USB 存储通知(StorageNotification)
└── tests/                         # 测试代码

关键statusbar/ 目录不仅管状态栏,SystemBars.java 同时负责状态栏和导航栏的创建与控制;stackdivider/tv/ 下的 PipUI 也属于子模块,目录名容易让人忽略它们。

四、AOSP7 SystemUI 子模块全景

在 AOSP7 中,SystemUI 的子模块组件列表不是 res/values/config.xml 里的 XML 字符串数组,而是硬编码SystemUIApplication 里的一个 Class<?>[] 数组。启动时通过 SystemUIFactory 反射创建每个组件的实例,再逐一调用 start()。这个数组的定义如下:

源码路径frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java

java 复制代码
public class SystemUIApplication extends Application {
    // ...
    private final Class<?>[] SERVICES = new Class[] {
            com.android.systemui.tuner.TunerService.class,
            com.android.systemui.keyguard.KeyguardViewMediator.class,
            com.android.systemui.recents.Recents.class,
            com.android.systemui.volume.VolumeUI.class,
            Divider.class,
            com.android.systemui.statusbar.SystemBars.class,
            com.android.systemui.usb.StorageNotification.class,
            com.android.systemui.power.PowerUI.class,
            com.android.systemui.media.RingtonePlayer.class,
            com.android.systemui.keyboard.KeyboardUI.class,
            com.android.systemui.tv.pip.PipUI.class,
            com.android.systemui.shortcut.ShortcutKeyDispatcher.class,
            com.android.systemui.VendorServices.class
    };
    // 每个用户单独启动的子集
    private final Class<?>[] SERVICES_PER_USER = new Class[] {
            com.android.systemui.recents.Recents.class,
            com.android.systemui.tv.pip.PipUI.class
    };
}

关键设计SERVICES 是硬编码的 Class<?>[],而非 XML 配置------子模块的增删要改这一处源码并重新编译,运行时无法动态调整;数组顺序即启动顺序。

每个组件都继承自 SystemUI 抽象基类,实现 start() 方法。

下表汇总各子模块的核心类与主要职责,按"系统栏 / 面板 / 周边子系统"的顺序排列:

模块 核心类 主要职责
StatusBar PhoneStatusBar 状态栏视图、通知图标、下拉手势
NavigationBar NavigationBarView 导航栏三键、布局管理
NotificationPanel NotificationPanelView 通知面板展开/折叠、通知条目管理
QuickSettings QSPanel / QSTileHost 快捷开关面板、Tile 增删改
Keyguard KeyguardViewMediator 锁屏调度、安全认证
Recents Recents 最近任务列表展示
VolumeUI VolumeUI 音量调节对话框
PowerUI PowerUI 低电量/过热警告
Divider Divider 分屏功能适配(AOSP7 新增)
Screenshot SaveImageInBackgroundTask 截屏保存与通知
RingtonePlayer RingtonePlayer 系统铃声播放

五、SystemUI 与系统服务的交互全景

SystemUI 不是一个孤立的模块,它与多个系统服务紧密协作。下图展示了核心交互关系:

复制代码
┌─────────────────────────────────────────────────────────────┐
│                     SystemServer 进程                        │
│  ┌──────────┐  ┌──────────┐  ┌──────────────────────┐      │
│  │   AMS    │  │   WMS    │  │NotificationManagerSvc │      │
│  └────┬─────┘  └────┬─────┘  └──────────┬───────────┘      │
│       │              │                   │                   │
│  ┌────┴──────────────┴───────────────────┴──────────┐      │
│  │            StatusBarManagerService               │      │
│  └────────────────────────┬─────────────────────────┘      │
└───────────────────────────┼────────────────────────────────┘
                            │ Binder IPC
┌───────────────────────────┼────────────────────────────────┐
│              SystemUI 进程 │                                │
│  ┌────────────────────────┴────────────────────────┐       │
│  │                 CommandQueue                     │       │
│  └────────┬──────────┬──────────┬──────────────────┘       │
│           │          │          │                           │
│  ┌────────┴──┐ ┌─────┴────┐ ┌──┴──────────┐               │
│  │PhoneStatus│ │ Keyguard │  │  Recents    │               │
│  │   Bar     │ │ ViewMed  │  │             │               │
│  └───────────┘ └──────────┘ └─────────────┘               │
└─────────────────────────────────────────────────────────────┘

关键交互说明

  1. 与 WMS 交互 :SystemUI 通过 WindowManager.LayoutParams 创建系统级窗口(TYPE_STATUS_BARTYPE_NAVIGATION_BARTYPE_KEYGUARD_DIALOG),这些窗口具有最高显示优先级。

  2. 与 AMS 交互:获取当前前台应用信息、处理最近任务列表、响应系统配置变化。

  3. 与 NMS(NotificationManagerService)交互 :通过 StatusBarManagerService 作为桥梁,NMS 将通知信息传递给 SystemUI 的 CommandQueue,再由 PhoneStatusBar 渲染到状态栏和通知面板。

  4. 与 StatusBarManagerService 交互 :SystemUI 通过 CommandQueue 实现了 IStatusBar 接口,作为 NMS 的回调,接收通知增删、系统图标更新等指令。

  5. 与 PhoneWindowManager 交互:处理导航栏按键事件、沉浸式模式切换、锁屏/解锁状态的协调。

六、AOSP7 SystemUI 的版本特征

相比后续版本,AOSP7 的 SystemUI 有以下显著特征:

特征 AOSP7 AOSP8+
分屏功能 新增 Divider 模块 完善
画中画(PiP) 仅 TV 支持 8.0 手机全面支持
通知渠道 不支持 8.0 引入 NotificationChannel
锁屏通知 基础支持 8.0+ 更细粒度控制
快捷设置 基础 Tile 系统 9.0+ 更灵活的自定义

七、本系列文章阅读导航

篇目 标题 核心内容
全景概览与架构设计(本文) 模块定位、目录结构、子模块总览
启动流程深度解析 SystemServer→SystemUIService→startServicesIfNeeded
StatusBar 状态栏源码分析 PhoneStatusBar、makeStatusBarView、图标管理
NavigationBar 导航栏与 SystemBars NavigationBarView、KeyButtonView、沉浸式模式
通知系统:从 NMS 到 SystemUI 通知发送接收链路、NotificationEntry、通知面板
QuickSettings 快捷设置面板 QSPanel、QSTileHost、Tile 管理
Keyguard 锁屏模块深度解析 KeyguardViewMediator、安全锁屏/滑动锁屏
Recents 最近任务与其他子系统 Recents、VolumeUI、PowerUI、Screenshot、定制实战

八、写给读者

如果你是第一次接触 SystemUI 源码,建议先通读本文建立全局认知,然后按照从"启动流程"到"核心模块"再到"周边子系统"的顺序逐篇阅读。每篇文章都配有源码路径、关键代码片段和架构图,建议打开 AOSP 源码对照阅读,效果更佳。

学习建议

  • 先理清 SystemUI.java 基类和 SystemUIApplication 的启动机制
  • 再深入 PhoneStatusBar 理解状态栏这一核心枢纽
  • 然后逐个模块突破,理解各模块之间的数据流转
  • 最后尝试做一个简单的定制修改(如修改状态栏图标、添加自定义 Tile)

下一篇:AOSP7 SystemUI 源码解析(二):启动流程深度解析,我们将从 SystemServer 的 startSystemUi() 开始,逐层追踪 SystemUI 的完整启动链路。

相关推荐
2501_916008892 小时前
如何实现iOS App代码混淆:SwiftShield使用指南
android·ios·小程序·https·uni-app·iphone·webview
恋猫de小郭2 小时前
AndroidX 新增 Security State ,支持可编程的系统安全状态查询
android·前端·flutter
AFinalStone3 小时前
Android7 SystemUI 源码解析(六)QuickSettings快捷设置面板
android·systemui
Kapaseker3 小时前
你有搞明白 Volatile 什么意思吗?
android·kotlin
美狐美颜SDK开放平台3 小时前
直播APP源码与视频美颜sdk如何配合?一套完整开发思路
android·人工智能·计算机视觉·音视频·直播美颜sdk
心平气和量大福大3 小时前
android-权限
android·java
2501_916008893 小时前
怎么用 Godot 导出 iOS 应用并上架 App Store?签名字段该填什么?
android·ios·小程序·https·uni-app·iphone·webview
智慧物业老杨6 小时前
物业日常巡查的数智化重构:从“打卡式巡检“到“闭环式风控“
android·java·人工智能·系统架构·rxjava
alexhilton12 小时前
藏在设备上的秘密,终究藏不住
android·kotlin·android jetpack