环境:android13.0.0_r6

1、SystemUI介绍

1.1、SystemUI摘要

1
2
在Android系统中SystemUI是以应用的形式运行在Android系统当中,即编译SystemUI模块会生产APK文件,源代码路径
在frameworks/base/packages/SystemUI/,安装路径system/priv-app/-SystemUI。

1.2、什么是SystemUI

1
2
3
4
5
6
7
8
9
在前文1.1章节中可知,SystemUI是一个普通的APK文件,即是一个普通的APP,但是,手机使用者看见的所有SystemUI的内容都不像是
一个APP,为什么?既然是一个应用,就是完成特定的功能,SystemUI主要完成的功能有:
(1)、Status bars
(2)、Navigation bars
(3)、Notification
(4)、Lockscreen
(5)、Quick settings
(6)、Overview(recent task switcher)
(7)、VolumeUI

img
img

2、SystemUI的架构

SystemUI的整体架构:

Android SystemUI采用了MVC(Model-View-Controller)架构,以实现界面元素的管理和交互。
它由多个关键组件组成,包括状态栏、导航栏、通知管理器、快捷设置等。
各个组件的功能和相互关系:

1
2
3
4
5
6
7
8
9
10
11
12
13
状态栏(Status Bar):显示系统状态信息,如时间、电池电量、信号强度等,并提供快速访问通知和快捷设置的入口。

导航栏(Navigation Bar):提供设备导航和操作控制,包括返回、主页和最近任务等按钮。

通知管理器(Notification Manager):负责接收、管理和展示通知,包括应用推送的通知和系统事件的通知。

快捷设置(Quick Settings):提供快速访问常用系统设置的面板,如Wi-Fi、蓝牙、亮度等,以方便用户进行快速调整。

锁屏界面(Lock Screen):显示在设备锁定状态下的界面,提供时间、日期、通知预览和快速启动应用等功能。

系统UI控制器(System UI Controller):作为整个SystemUI的控制中心,负责协调各个组件之间的交互和管理。

其他辅助组件:还有一些辅助组件,如电源管理器、音量控制器等,用于管理设备的电源和音量控制。

这些组件相互配合,构成了SystemUI的整体架构。每个组件负责不同的功能和交互,并通过事件触发和消息传递等机制相互关联。理解SystemUI的架构和组件之间的相互关系,有助于我们深入了解系统界面的实现原理,并进行自定义和扩展。

3、SystemUI的启动过程

SystemUI任何内容都不像一个APP,自然它的启动也不像大多APP一样启动一个Activity。SystemUI顾名思义就是全局UI,必须在开机过程中完成启动,并不可退出。
回顾Android系统开机的过程,会创建server进程维护系统各种服务,如下:

1
2
3
4
5
6
7
Android系统启动流程:
1.按下电源,系统上电
2.从固定地址启动固化在ROM的BootLoader程序
3.启动Linux内核,加载init进程
4.启动init进程,fork出zygote进程
5.启动SystemServer,启动Binder线程池以及各种服务
6.AMS启动Launcher, 然后你就看到该看到的了

SystemUI作为系统主要进程,就是在SystemServer启动的服务其中之一

SystemServer.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
   public static void main(String[] args) {
new SystemServer().run();
}

private void run() {
......
// Start services.
try {
traceBeginAndSlog("StartServices");
startBootstrapServices();
startCoreServices();
startOtherServices();
SystemServerInitThreadPool.shutdown();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
traceEnd();
}
......
}

private void startOtherServices() {
......
mActivityManagerService.systemReady(() -> {
Slog.i(TAG, "Making services ready");
traceBeginAndSlog("StartActivityManagerReadyPhase");
......
try {
startSystemUi(context, windowManagerF);
} catch (Throwable e) {
reportWtf("starting System UI", e);
}
......
}
}

static final void startSystemUi(Context context, WindowManagerService windowManager) {
PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class);
Intent intent = new Intent();
intent.setComponent(pm.getSystemUiServiceComponent());//从本地获取systemuiService的包名
intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
//Slog.d(TAG, "Starting service: " + intent);
context.startServiceAsUser(intent, UserHandle.SYSTEM);
windowManager.onSystemUiStarted();
}

总结下代码流程:SystemServermain()方法会调用SystemServer.run()方法,在run方法中,会启动bootStrapService,coreService,以及其他服务otherService,在startOtherServices()中,会注册AMS的systemReady回调,在回调中启动SystemUI,其实就是启动了SystemUIService。

SystemUIService.java

1
2
3
4
5
6
7
//frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIService.java
@Override
public void onCreate() {
super.onCreate();
((SystemUIApplication) getApplication()).startServicesIfNeeded();
.....
}

SystemUIApplication.java

1
2
3
4
5
6
7
8
9
10
11
12
13
//frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
public void startServicesIfNeeded() {
final String vendorComponent = SystemUIFactory.getInstance()
.getVendorComponent(getResources());
// Sort the startables so that we get a deterministic ordering.
// TODO: make #start idempotent and require users of CoreStartable to call it.
Map<Class<?>, Provider<CoreStartable>> sortedStartables = new TreeMap<>(
Comparator.comparing(Class::getName));
sortedStartables.putAll(SystemUIFactory.getInstance().getStartableComponents());
sortedStartables.putAll(SystemUIFactory.getInstance().getStartableComponentsPerUser());
startServicesIfNeeded(
sortedStartables, "StartServices", vendorComponent);
}

SystemUIApplication.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
private void startServicesIfNeeded(
Map<Class<?>, Provider<CoreStartable>> startables,
String metricsPrefix,
String vendorComponent) {
if (mServicesStarted) {//如果服务已经启动,则直接返回。
return;
}
//初始化一个 CoreStartable 类型的数组 mServices,它的长度为 startables 元素的数量加上(如果有)一个 vendorComponent 的长度。
mServices = new CoreStartable[startables.size() + (vendorComponent == null ? 0 : 1)];
//如果检测到系统还未启动完成,则检查系统属性 “sys.boot_completed” 是否为 1。如果是 1,则设置启动完成标志,并记录日志
if (!mBootCompleteCache.isBootComplete()) {
// check to see if maybe it was already completed long before we began
// see ActivityManagerService.finishBooting()
if ("1".equals(SystemProperties.get("sys.boot_completed"))) {
mBootCompleteCache.setBootComplete();
if (DEBUG) {
Log.v(TAG, "BOOT_COMPLETED was already sent");
}
}
}
//使用 mSysUIComponent(也就是 SystemUI 的组件)创建一个 DumpManager 对象,用于管理系统 UI 相关的 dump 文件
mDumpManager = mSysUIComponent.createDumpManager();
//记录一条日志,表示正在启动 SystemUI 服务。
Log.v(TAG, "Starting SystemUI services for user " +
Process.myUserHandle().getIdentifier() + ".");
TimingsTraceLog log = new TimingsTraceLog("SystemUIBootTiming",
Trace.TRACE_TAG_APP);
log.traceBegin(metricsPrefix);

int i = 0;
//对于 startables 中的每个元素,获取它的类名和 CoreStartable 实现类的提供者,然后初始化一个 int 类型的变量 j,
//并将其赋值为 i,以便接下来在lambda 函数中使用。接着调用 timeInitialization 方法,其作用是计时和执行初始化
for (Map.Entry<Class<?>, Provider<CoreStartable>> entry : startables.entrySet()) {
String clsName = entry.getKey().getName();
int j = i; // Copied to make lambda happy.
timeInitialization(
clsName,
() -> mServices[j] = startStartable(clsName, entry.getValue()),
log,
metricsPrefix);
i++;
}
//如果 vendorComponent 不为 null,则调用 timeInitialization 方法,初始化包含 vendorComponent 的 CoreStartable 实现类并将其存储在 \
// mServices 数组的最后一个位置。
if (vendorComponent != null) {
timeInitialization(
vendorComponent,
() -> mServices[mServices.length - 1] =
startAdditionalStartable(vendorComponent),
log,
metricsPrefix);
}
//对于 mServices 数组中的每个元素,如果系统已经启动完成,则调用其 onBootCompleted 方法,表示启动完成了。然后注册每个
// CoreStartable 实现类的 dump,以便可以进行 dumpsys 命令后的分析

for (i = 0; i < mServices.length; i++) {
if (mBootCompleteCache.isBootComplete()) {
mServices[i].onBootCompleted();
}
mDumpManager.registerDumpable(mServices[i].getClass().getName(), mServices[i]);
}
//执行 SystemUI 组件的 InitController 中注册的所有后置初始化任务
mSysUIComponent.getInitController().executePostInitTasks();
//使用 TimingsTraceLog 停止记录启动时间的追踪,记录所有记录的时间,并结束执行 startServicesIfNeeded 方法的过程。
log.traceEnd();

mServicesStarted = true;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!-- SystemUI Services: The classes of the stuff to start. -->
<string-array name="config_systemUIServiceComponents" translatable="false">
<item>com.android.systemui.Dependency</item>
<item>com.android.systemui.util.NotificationChannels</item>
<item>com.android.systemui.statusbar.CommandQueue$CommandQueueStart</item>
<item>com.android.systemui.keyguard.KeyguardViewMediator</item>
<item>com.android.systemui.recents.Recents</item>
<item>com.android.systemui.volume.VolumeUI</item>
<item>com.android.systemui.stackdivider.Divider</item>
<item>com.android.systemui.SystemBars</item>
<item>com.android.systemui.usb.StorageNotification</item>
<item>com.android.systemui.power.PowerUI</item>
<item>com.android.systemui.media.RingtonePlayer</item>
<item>com.android.systemui.keyboard.KeyboardUI</item>
<item>com.android.systemui.pip.PipUI</item>
<item>com.android.systemui.shortcut.ShortcutKeyDispatcher</item>
<item>@string/config_systemUIVendorServiceComponent</item>
<item>com.android.systemui.util.leak.GarbageMonitor$Service</item>
<item>com.android.systemui.LatencyTester</item>
<item>com.android.systemui.globalactions.GlobalActionsComponent</item>
<item>com.android.systemui.ScreenDecorations</item>
<item>com.android.systemui.fingerprint.FingerprintDialogImpl</item>
<item>com.android.systemui.SliceBroadcastRelayHandler</item>
</string-array>

<!-- SystemUI vender service, used in config_systemUIServiceComponents. -->
<string name="config_systemUIVendorServiceComponent" translatable="false">com.android.systemui.VendorServices</string>

SystemUIService的onCreate()方法中,直接调用SystemUIApplication.startServicesIfNeeded()方法,最终会将所有服务一一加载并通过start()方法启动起来。

至此,SystemUI基本启动流程就结束了。