在前文中已经知道 SystemUI
是由 SystemServer
启动的。更准确的说是 SystemServer
启动了 SystemUI
中的名为 SystemUIService
的服务,然后在 SystemUIApplication
中启动了所有服务组件。
这些服务组件在 config.xml
中定义
frameworks/base/packages/SystemUI/res/values/config.xml
<!-- SystemUI Services: The classes of the stuff to start. -->
<string-array name="config_systemUIServiceComponents" translatable="false">
<item>com.android.systemui.util.NotificationChannels</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.statusbar.phone.StatusBar</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.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.biometrics.AuthController</item>
<item>com.android.systemui.SliceBroadcastRelayHandler</item>
<item>com.android.systemui.statusbar.notification.InstantAppNotifier</item>
<item>com.android.systemui.theme.ThemeOverlayController</item>
<item>com.android.systemui.accessibility.WindowMagnification</item>
<item>com.android.systemui.accessibility.SystemActions</item>
<item>com.android.systemui.toast.ToastUI</item>
<item>com.android.systemui.wmshell.WMShell</item>
</string-array>
这些都是在 SystemUI
处理各种业务逻辑的关键代码,一共有20多个组件,从另外一个侧面可以看出 SystemUI
的复杂程度。它们的介绍也可以在源码阅读官网上查看[1]
这里简单说明一下
com.android.systemui.Dependency
提供依赖注入实现(这个在最新的源码 config_systemUIServiceComponents 里面已经是没有了,但如果你看 Android 10 这个类还是存在的)
com.android.systemui.util.NotificationChannels
用来处理通知的逻辑
com.android.systemui.keyguard.KeyguardViewMediator
用来处理键盘锁状态
com.android.systemui.recents.Recents
处理最新任务列表的逻辑
com.android.systemui.volume.VolumeUI
监听音量,并决定是否显示音量的对话框
com.android.systemui.status.phone.StatusBar
状态栏,也包含了通知栏和其它重要的 UI 交互,例如键盘锁等。这里也会监听通知
com.android.systemui.usb.StorageNotification
监听 USB 连接状态并发送通知进行提示
com.android.systemui.power.PowerUI
监听电量状态并在低电量时发送通知
com.android.systemui.media.RingtonePlayer
用于播放铃声
com.android.systemui.keyboard.KeyboardUI
键盘锁 UI
com.android.systemui.shortcut.ShortcutKeyDispatcher
向 SystemUI 组件派发快捷键
@string/config_systemUIVendorServiceComponent
这里可以定义厂商定制的组件
com.android.systemui.util.leak.GarbageMonitor$Service
用于监控内存泄漏的服务
com.android.systemui.LatencyTester
仅在 debug 环境执行,用于监听系统测试延迟的模拟动作
com.android.systemui.globalactions.GlobalActionsComponent
用于显示全局对话框(例如长按电源按键)
com.android.systemui.ScreenDecorations
处理页面中的显示的形状(如圆角)
com.android.systemui.biometrics.BiometricDialogImpl
生物识别 UI (如指纹识别、解锁等页面?)
com.android.systemui.wmshell.WMShell
转发 SysUI 事件到 WM Shell
这些服务组件不是 Android
系统四大组件里面的服务。这些组件在实现上都是普通的 Java
类,实际上这些组件都继承于 SystemUI
这个类
frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUI.java
/**
* A top-level module of system UI code (sometimes called "system UI services" elsewhere in code).
* Which SystemUI modules are loaded can be controlled via a config resource.
*
* @see SystemUIApplication#startServicesIfNeeded()
*/
public abstract class SystemUI implements Dumpable {
protected final Context mContext;
public SystemUI(Context context) {
mContext = context;
}
public abstract void start();
protected void onConfigurationChanged(Configuration newConfig) {
}
@Override
public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
}
protected void onBootCompleted() {
}
public static void overrideNotificationAppName(Context context, Notification.Builder n,
boolean system) {
final Bundle extras = new Bundle();
String appName = system
? context.getString(com.android.internal.R.string.notification_app_name_system)
: context.getString(com.android.internal.R.string.notification_app_name_settings);
extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME, appName);
n.addExtras(extras);
}
}
可以看出这个类并不复杂,从注释中也可以知道这些组件被称为 system UI services
。它是抽象的,它的 start()
是需要在子类中实现的。
从前文已经了解到每个组件是在 SystemUIApplication#startServicesIfNeeded()
中通过反射构造后,然后调用了 start()
进行启动。当然还有 onBootCompleted()
方法也见过了,它会在 SystemUIApplication#onCreate()
注册系统启动完成的监听动作,待系统启动完成后会执行这个方法。
类结构图可以参考
这里只画出了4个实现类,其它可以自行脑补
了解这些有什么用?
当然如果你不是做系统应用开发,这些知识对你来说可能用处不那么大。尤其当你只是纯上层应用开发者,了解到其中大概的原理也就差不多了,根本不用深究; 但是如果你需要深度定制系统的 UI 界面,只是知道其中的大概,我觉得是不够的。在对这些组件有了一个比较宏观的认识之后,然后能够根据需求深入理解其运行机制,接一下就可以对其改造,进行二次创造了。
•在线源码阅读 https://cs.android.com
[1]
源码阅读官网上查看: https://cs.android.com/android/platform/superproject/+/android-12.0.0_r4:frameworks/base/packages/SystemUI/;bpv=0;bpt=0