zl程序教程

您现在的位置是:首页 >  Javascript

当前栏目

SystemUI 开发之服务组件概览(二)

2023-04-18 14:40:06 时间

0x00 介绍

在前文中已经知道 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

0x01 组件结构

这些服务组件不是 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个实现类,其它可以自行脑补

0x02 思考

了解这些有什么用?

当然如果你不是做系统应用开发,这些知识对你来说可能用处不那么大。尤其当你只是纯上层应用开发者,了解到其中大概的原理也就差不多了,根本不用深究; 但是如果你需要深度定制系统的 UI 界面,只是知道其中的大概,我觉得是不够的。在对这些组件有了一个比较宏观的认识之后,然后能够根据需求深入理解其运行机制,接一下就可以对其改造,进行二次创造了。

0x03 引用

•在线源码阅读 https://cs.android.com

References

[1] 源码阅读官网上查看: https://cs.android.com/android/platform/superproject/+/android-12.0.0_r4:frameworks/base/packages/SystemUI/;bpv=0;bpt=0