SystemUI 解析

android SystemUI全解析 本文由以下博客转载解释而成: Android 4.0 ICS SystemUI浅析——StatusBar加载流程分析 阅读详情
AI摘要

本文详细探讨了AndroidSystemUI的架构,包括其组件间的交互、依赖注入(Dagger2)的使用,以及启动流程中的关键步骤。重点介绍了SystemUI如何作为一个常驻应用程序独立运行,以及其在Android14中可能的重构趋势。

首语

SystemUI(System User Interface)是Android 系统为用户提供的系统级别的信息显示与交互的UI组件应用程序,包含状态栏、导航栏、锁屏、通知面板、快速设置、最近任务等,它们各部分独立,各尽其责。

SystemUI是一个常驻应用程序,只要系统运行,它就会一直运行,即使被杀死也会重新启动。

源码目录

SystemUI源码目录在frameworks/base/package下,和Settings不一样,它不在package/apps下。

从Android.bp文件中可以得出,模块名为SystemUI。

架构

SystemUI各组件经常会互相交互,例如点击通知面板通知在锁屏情况下会跳转锁屏页面先解锁,解锁情况下跳转锁屏内容页面,因此通知面板需要清楚锁屏状态来进行处理。为此需要设计好架构,还轻松获取到各个组件,避免产生很多的创建代码,SystemUI使用了依赖注入自动创建对象,SystemUI使用Dagger2来作为依赖注入库,管理组件。

Android系统中,为了适应多元化场景,诸如TV、Car,它们又是不同的UI组件,同时满足模块化设计,因此将SytemUI独立成一个单独的、常驻内存的应用程序。

SystemUI各种组件UI均存在UIController来进行UI逻辑的处理和交互,不同组件源码通过目录清晰划分。

关于Dagger2,可参考以下文档:
Android 官方:https://developer.android.google.cn/training/dependency-injection/dagger-basics?hl=zh_cn
Dagger: https://dagger.dev/dev-guide

AndroidManifest

由Manifest可以看出,SystemUI是一个比较特殊的应用程序,有许多特定设置项。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
        package="com.android.systemui"
        <!--指定共享的uid-->
        android:sharedUserId="android.uid.systemui"
        xmlns:tools="http://schemas.android.com/tools"
        coreApp="true">
     <application
        	android:name=".SystemUIApplication"
        	android:persistent="true"
            <!--不允许清除应用数据-->
        	android:allowClearUserData="false"
        	android:backupAgent=".backup.BackupHelper"
            <!--应用程序被恢复后继续运行-->
        	android:killAfterRestore="false"
            <!--启用硬件加速-->
        	android:hardwareAccelerated="true"
        	android:label="@string/app_label"
        	android:icon="@drawable/icon"
            <!--指定进程-->
        	android:process="com.android.systemui"
        	android:supportsRtl="true"
        	android:theme="@style/Theme.SystemUI"
            <!--默认存储空间重定向到data/user_de-->
        	android:defaultToDeviceProtectedStorage="true"
            <!--DirectBoot 模式下可以启动-->
        	android:directBootAware="true"
        	tools:replace="android:appComponentFactory"
            <!--指定应用程序组件工厂,动态创建和初始化组件-->
        	android:appComponentFactory=".SystemUIAppComponentFactory">
     </application>       
</manifest>

启动流程

在SystemServer 进程启动过程文章中,我们清楚SystemServer进程主要工作是启动系统服务,其中在startOtherServices方法中,当AMS系统服务进入就绪状态时,会调用startSystemUi方法来启动SystemUI,其中AMS是在startBootstrapServices方法中被启动的。在startSystemUi方法中启动了一个服务,服务intent的component通过PackageManagerInternal类的getSystemUiServiceComponent方法获取,PackageManagerInternal是一个抽象类,它的实现在PackageManagerInternalBase类中,可以看到getSystemUiServiceComponent实现中返回了config_systemUIServiceComponent字符串。

源码路径:frameworks\base\services\java\com\android\server\SystemServer.java

private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
    ...
    mActivityManagerService.systemReady(() -> {
        ...
        t.traceBegin("StartSystemUI");
        try {
            startSystemUi(context, windowManagerF);
        } catch (Throwable e) {
            reportWtf("starting System UI", e);
        }
        t.traceEnd();
    },t);
}
private static void startSystemUi(Context context, WindowManagerService windowManager) {
        PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class);
        Intent intent = new Intent();
        intent.setComponent(pm.getSystemUiServiceComponent());
        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
        //Slog.d(TAG, "Starting service: " + intent);
        context.startServiceAsUser(intent, UserHandle.SYSTEM);
        windowManager.onSystemUiStarted();
    }

源码路径:frameworks\base\services\core\java\com\android\server\pm\PackageManagerInternalBase.java

@Override
@Deprecated
public final ComponentName getSystemUiServiceComponent() {
    return ComponentName.unflattenFromString(getContext().getResources().getString(
                com.android.internal.R.string.config_systemUIServiceComponent));
}

可以看到指定的Component包名为com.android.systemui,类名为com.android.systemui.SystemUIService。

到这里我们就清楚,SystemUI是SystemServer进程启动SystemUIService来启动的。

源码路径:frameworks\base\core\res\res\values\config.xml

<!-- SystemUi service component -->
<string name="config_systemUIServiceComponent" translatable="false"
            >com.android.systemui/com.android.systemui.SystemUIService</string>

SystemUIService类中调用SystemUIApplication类的startServicesIfNeeded方法。

源码路径:frameworks\base\packages\SystemUI\src\com\android\systemui\SystemUIService.java

@Override
public void onCreate() {
     super.onCreate();
     // Start all of SystemUI
     ((SystemUIApplication) getApplication()).startServicesIfNeeded();
	 ...
    }

首先获取定制的系统UI组件,其为VenderService。继续通过getStartableComponents和getStartableComponentsPerUser方法获取组件

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

public void startServicesIfNeeded() {
    	//定制系统UI组件
        final String vendorComponent = SystemUIFactory.getInstance()
                .getVendorComponent(getResources());
        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);
}

源码路径:frameworks\base\packages\SystemUI\src\com\android\systemui\SystemUIFactory.java

//    <string name="config_systemUIVendorServiceComponent" translatable="false">com.android.systemui.VendorServices</string>
public String getVendorComponent(Resources resources) {
        return resources.getString(R.string.config_systemUIVendorServiceComponent);
}
public Map<Class<?>, Provider<CoreStartable>> getStartableComponents() {
        return mSysUIComponent.getStartables();
}
public Map<Class<?>, Provider<CoreStartable>> getStartableComponentsPerUser() {
        return mSysUIComponent.getPerUserStartables();
}

这里使用了Dagger2的@IntoMap注入相关类,只要是继承CoreStartable类的都将会被注入。

源码路径:frameworks\base\packages\SystemUI\src\com\android\systemui\dagger\SysUIComponent.java

@SysUISingleton
@Subcomponent(modules = {
        DefaultComponentBinder.class,
        DependencyProvider.class,
        SystemUIBinder.class,
        SystemUIModule.class,
        SystemUICoreStartableModule.class,
        ReferenceSystemUIModule.class})
public interface SysUIComponent {
    Map<Class<?>, Provider<CoreStartable>> getStartables();
    @PerUser Map<Class<?>, Provider<CoreStartable>> getPerUserStartables();
}

注入方法如下,相关注入结束后,继续回到SystemUIApplication类的startServicesIfNeeded方法。

源码路径:frameworks\base\packages\SystemUI\src\com\android\systemui\dagger\SystemUICoreStartableModule.kt

@Module
abstract class SystemUICoreStartableModule {
     /** Inject into AuthController.  */
    @Binds
    @IntoMap
    @ClassKey(AuthController::class)
    abstract fun bindAuthController(service: AuthController): CoreStartable

    /** Inject into ClipboardListener.  */
    @Binds
    @IntoMap
    @ClassKey(ClipboardListener::class)
    abstract fun bindClipboardListener(sysui: ClipboardListener): CoreStartable
    ......
}

获取所有组件后,启动所有组件,至此System UI和SystemUI所有组件启动完成。

private void startServicesIfNeeded(
            Map<Class<?>, Provider<CoreStartable>> startables,
            String metricsPrefix,
            String vendorComponent) {
        if (mServicesStarted) {
            return;
        }
        mServices = new CoreStartable[startables.size() + (vendorComponent == null ? 0 : 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");
                }
            }
        }

        mDumpManager = mSysUIComponent.createDumpManager();

        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;
        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++;
        }

        if (vendorComponent != null) {
            timeInitialization(
                    vendorComponent,
                    () -> mServices[mServices.length - 1] =
                            startAdditionalStartable(vendorComponent),
                    log,
                    metricsPrefix);
        }

        for (i = 0; i < mServices.length; i++) {
            if (mBootCompleteCache.isBootComplete()) {
                mServices[i].onBootCompleted();
            }

            mDumpManager.registerDumpable(mServices[i].getClass().getName(), mServices[i]);
        }
        mSysUIComponent.getInitController().executePostInitTasks();
        log.traceEnd();

        mServicesStarted = true;
    }
private CoreStartable startStartable(String clsName, Provider<CoreStartable> provider) {
        if (DEBUG) Log.d(TAG, "loading: " + clsName);
        return startStartable(provider.get());
    }

    private CoreStartable startStartable(CoreStartable startable) {
        if (DEBUG) Log.d(TAG, "running: " + startable);
        startable.start();

        return startable;
    }

总结

SystemUI是Android系统中与用户交互频繁的UI组件应用程序,地位不言而喻。后续会对SystemUI中重要的组件进行单独分析,深入了解。同时对于这个一个UI组件应用程序,Android 14引入了Jetpack Compse进行部分UI代码的重构,在保持稳定性的前提下官方会持续进行重构,到时架构及实现将会发生重大变化。

官方文档:frameworks/base/package/SystemUI/docs/

Android SystemUI 介绍 什么是SystemUI?Android SystemUi是指Android操作系统中的系统用户界面,它是用户与设备交互的界面。SystemUi提供了状态栏、导航栏、通知中心等重要的用户界面元素,这些元素可以帮助用户快速地访问设备的各种功能和信息。主要模块如下:1、NavigationBar(导航栏):NavigationBar是位于屏幕底部的导航界面,提供了返回、主页和最近任务等导航操作的按钮。它使用户能够浏览应用程序和系统功能,如切换应用、返回主屏幕等。 阅读详情

相关推荐

SystemUi概述

一.SystemUI概述 在Android系统中SystemUI是以应用的形式运行的。即编译SystemUI会产生APK文件。但它和普通的APK不同,它是开机启动的A并且不可以退出, SystemUI顾名思义是系统用户界面。它为系统提供了基础的显示界面。比如:屏幕顶端 的状态栏、屏幕底部的导航栏、下拉界面的快速设置栏、 通知栏、锁屏界面,音量调节对话框、截屏显示界面等功能。 1.SystemUI路径 与Packages/apps/下许多模块不同的是,SystemUI属于Android ...

xxdw1992的博客 5658

什么是SystemUI?简单分析

SystemUI概览 SystemUI属于系统级的apk,位置在frameworks\base\packages\SystemUI,主要功能有: 状态栏信息显示,比如电池,wifi信号,3G/4G等icon显示 通知面板,比如系统消息,第三方应用消息 近期任务栏显示面板,比如长按近期任务快捷键,显示近期使用的应用 截图服务 壁纸服务 …… SystemUI的启动流程 SystemServer启动后,会在Main Thread启动ActivityManagerService,当Activi

Jason_Lee155的博客 1万+

SystemUI深入解析(一)

SystemUI深入解析6的飞起,666!!!

qq_35449657的博客 759

SystemUI详解

SystemUI是Android操作系统的一个关键组件,主要负责管理和提供用户界面的核心元素,如状态栏、导航栏和锁屏界面等。从下面两点出发了解SystemUI的特性:SystemUI是操作系统中的一个系统级应用程序,负责管理和呈现用户界面的重要元素。它提供了与用户交互的界面元素,包括状态栏、导航栏、通知和快捷设置等。SystemUI通过提供用户界面和交互方式,使用户能够轻松访问系统功能和通知。SystemUI紧密集成在Android操作系统中,作为核心组件之一。

Ocean的博客 4326

Android 系统的 SystemUI 分析

SystemUI 的源代码位于 frameworks/base/packages/SystemUI 目录下,通过注册相应的组件来实现系统启动时的自动运行。其中,StatusBar 和 NavigationBar 是两个重要的类,分别处理状态栏和导航栏的相关逻辑。以上是对 Android 系统的 SystemUI 进行的简要分析,以及相关的源代码示例。SystemUI 是 Android 系统中一个重要的系统界面组件,它负责管理屏幕上的状态栏、导航栏等系统级 UI 元素。

2301_78484069的博客 850

SystemUI架构设计

SystemUI简介

ss520k的专栏 6190

Android SystemUI启动流程深度解析

Android SystemUI是系统的重要组成部分,负责状态栏、导航栏等用户界面的显示。其启动流程包括:Zygote进程孵化SystemServer进程,启动ActivityManagerService等核心服务;AMS通过启动SystemUIService来加载SystemUI组件;SystemUIApplication通过反射初始化StatusBar、NotificationPanel等核心模块。SystemUI与WindowManager紧密交互,以窗口形式展示界面元素。整个启动过程涉及多个系统服务

顾林海 3159

AutoCAD2014与ObjectARX开发环境搭建实战指南

本文提供了一份详细的AutoCAD2014与ObjectARX开发环境搭建实战指南。内容涵盖从AutoCAD2014、Visual Studio 2010及ObjectARX 2014 SDK的版本匹配与环境准备,到Wizard安装、编码问题解决、Visual Studio配置,并最终通过一个完整的绘图命令开发示例,手把手引导开发者创建并加载第一个可运行的ObjectARX插件,为后续深入开发奠定坚实基础。

weixin_28475533的博客 286

**SystemUI 超详细解析:架构、流程与核心实现**

**触发点**:`SystemServer` 完成关键服务初始化后,调用 `ActivityManagerService.systemReady()`,启动 SystemUI。// 调用每个组件的initialize()- **启动命令**:通过 `SystemService` 启动 `SystemUIService`。- **组件加载**:从 `config.xml` 加载所有 SystemUI 组件。##### **2. 与 ActivityManagerService 的协作**

u011228868的专栏 1592

SoapUI 5.0 模拟WebService接口实战:从WSDL文件到Mock服务端完整流程

本文详细介绍了如何使用SoapUI 5.0模拟WebService接口,从解析WSDL文件到搭建完整的Mock服务端流程。通过实战案例和效率技巧,帮助开发者快速掌握接口模拟技术,提升开发与测试效率。

weixin_26833139的博客 405

汽车ECU诊断入门:手把手教你用UDS协议(ISO14229)读取和清除故障码

本文详细介绍了如何使用UDS协议(ISO14229)进行汽车ECU诊断,包括故障码读取与清除的完整流程。从诊断环境搭建、UDS协议基础到实战案例分析,手把手教你掌握0x19诊断服务、安全访问机制等核心技能,适用于汽车电子工程师和诊断开发人员。

weixin_33701251的博客 452

OpenHarmony 源码解析之SystemUi—Statusbar(TS)

SystemUI应用是OpenHarmony中预置的系统应用,为用户提供系统相关信息展示及交互界面,包括系统状态、系统提示、系统提醒等,例如系统时间、电量信息。导入batteryInfo模块,监听系统电池事件,实时获取电池电量状态导入时间模块,调用JS内置函数,实时获取系统时间、日期、星期信息导入Wifi模块,监听设备Wlan通信与连接事件,实时获取Wifi开关、供电、连接名等信息。

2501_91726491的博客 1072

别再手动填序号了!用Python脚本在Arcgis属性表里实现分组自动编号(附完整代码)

本文详细介绍了如何利用Python脚本在Arcgis属性表中实现分组自动编号,告别低效的手工操作。通过核心代码解析和实战教程,帮助GIS工程师快速掌握自动化编号技术,提升工作效率并降低错误率。特别适合城市规划、国土调查等需要处理大量分组数据的场景。

weixin_42532473的博客 307

Android系统SystemUI启动过程解析

Android 系统 SystemUI 介绍 Android 的 SystemUI 其实就是 Android 的系统界面,它包括了界面上方的状态栏 status bar,下方的导航栏Navigation Bar,锁屏界面 Keyguard ,电源界面 PowerUI,近期任务界面 Recent Task 等等。对于用户而言,SystemUI 的改动是最能直观感受到的。因此,每个 Android 版本在 SystemUI 上都有比较大的改动。而对开发者而言,理解 Android SystemUI 对优化An

w2064004678的博客 653

Mumax3代码模板:从基础设置到材料参数优化

本文提供了一份详尽的Mumax3微磁学模拟代码模板,从基础网格设置、边界条件到核心材料参数(如钴的Msat、Aex、Ku1)配置与优化均有涵盖。文章深入解析了特征长度计算、初始化方法、弛豫与动力学模拟流程,并分享了并行计算与参数扫描等效率提升技巧,旨在帮助用户快速上手并优化模拟工作流。

moss5的博客 702

1.为什么要学习MATLAB

学习MATLAB

FPGA/MATLAB学习教程/源码/项目合作开发 5804

源码解析开机systemui启动流程

1.SystemServer.java 找到\frameworks\base\services\java\com\android\server\SystemServer main方法 public static void main(String[] args) { new SystemServer().run(); } run方法中会调用startBootstrapService...

baidu_33634330的博客 364

CEEMDAN算法及其应用

本博文主要介绍CEEMDAN算法的原理及其在信号去噪方面的应用

总结论文中的算法并给出论文的复现代码 6万+

android systemui解析

主要分析android的systemui业务,并以此为基础,扩展到view的绘制,事件处理,window管理等等。 这里是第一部分,systemui的view的初步加载。 Systemui的界面,一般形状是如绿色标示部分,拉下来后显示下面全图的样子。 对于view类的管理,可以用hierarchyviewer工具查看。这里也要详细介绍。 最外层的view是StatusbarWind

JeffTech的专栏 1801

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

SystemUI如何工作?启动流程与核心服务解析

本文深入解析了Android系统中SystemUI的启动流程与核心服务工作原理。SystemUI作为系统级应用,负责管理状态栏、导航栏、锁屏界面等关键用户交互元素。文章详细介绍了从SystemServer启动到各服务初始化的完整过程,并探讨了状态栏服务、锁屏服务等核心模块的实现机制,为开发者理解Android系统界面层提供了技术参考。

weixin_34014555的博客 420

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Android7 SystemUI 源码解析(五)通知系统——从 NMS 到 SystemUI

本文深入解析AOSP7通知系统,从应用调用NotificationManager.notify()出发,经由NotificationManagerService跨进程处理,生成StatusBarNotification并排序,最终通过INotificationListener投递至SystemUI。核心链路包括:应用侧封装通知、NMS入队与排序、监听器分发,全程基于异步Handler机制,确保高效响应。关键点为:单条通知不经过StatusBarManagerService,仅通过NotificationLi

AfinalStone的专栏 243

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

史上最详细的Android系统SystemUI 启动过程详细解析

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33941350的博客 378

Android14 SystemUI定制实战:锁屏与状态栏深度解析

SystemUI是Android系统用户界面的核心组件,负责锁屏、状态栏和快速设置面板等关键交互区域。其原理基于SystemUIApplication进程,通过KeyguardViewMediator和StatusBar等类管理视图层级与事件分发。在Android14中,SystemUI的模块化重构提升了定制灵活性,技术价值在于实现深度UI定制和系统优化。应用场景涵盖ROM开发、车机及平板设备定制,如修改锁屏快捷方式或状态栏图标。本文聚焦Android14 SystemUI的锁屏与状态栏定制,分享实战经验与

weixin_34372728的博客 422

Android SystemUI启动流程与核心组件解析

SystemUI作为Android系统的用户界面核心组件,承担状态栏、导航栏等系统级UI渲染任务。其基于系统服务架构运行,通过WindowManagerService实现窗口管理,采用模块化设计提升可维护性。从技术实现看,SystemUI进程由SystemServer动态创建,通过依赖注入解耦各功能模块,这种设计既保证了系统稳定性,又为ROM定制提供了灵活性。在移动开发领域,深入理解SystemUI启动机制对性能优化(如延迟初始化策略)和功能扩展(如通知中心定制)具有重要价值,尤其适用于系统层开发、Fram

weixin_29284201的博客 282
上一篇: 四大组件的工作过程
下一篇: Android View
八归少年
八归少年 新星创作者: 操作系统技术领域 新星创作者: 操作系统技术领域
博客等级 码龄9年 9011粉丝 63原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

八归少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值