SystemUI启动流程

目录

一、概述:

二、启动流程:

2.1在 framework 中的流程

小结一下

2.2在 SystemUI 中的流程:

SystemUIApplication:

SystemUIService:

小结一下


一、概述:

        作为Android系统核心应用,SystemUI负责反馈系统及应用状态并与用户保持大量的交互。耳熟能详的三栏:StatusBar(状态栏)、NavigationBar(导航栏)与Notification Panel(通知栏),以及Recents(近期任务界面),使用起来方便又快捷。

        有一点需要说明一下,Android 10之后近期列表的显示被移到Launcher  app里面了。在Launcher3的一个 类中TouchInteractionService.java   IBinder mMyBinder = new IOverviewProxy.Stub() 通过AIDL的方法与systemUI通信。

        大多数厂商会根据自身需求对 SystemUI 的样式进行深度定制,例如在我Redmi手机中的 SystemUI 长这样:

快捷键栏:

通知栏:


二、启动流程:

启动流程主要包括两个部分:

        1.在 framework 中启动 SystemUIService

        2.在 SystemUIService 中启动 SystemUI 所需的各种组件

2.1在 framework 中的流程

        SystemUI 是系统应用,所以它也是一个 APK,有入口 Application,只不过它是由 SystemServer 进程进行启动的。

1.这个就是 SystemServer 进程的入口,它会启动很多系统相关的应用,其中就包括 SystemUI。找到它的 main 方法:

从这个方法的注释来看,SystemServer 是由 zygote 进程启动的。

2.接下来看run() 方法:

 SystemServer负责系统中各种重要服务的启动,不巧,由于SystemUI的重要性,她也在被启动之列,虽然是处于“Other”的地位。

3.在startOtherServices中找到:

可以看到这里通过 PackageManagerInternal.getSystemUiServiceComponent() 获取到 SystemUIService 组件,然后通过 startServiceAsUser 方法启动了服务。

该service对应的详细参数是通过getSystemUiServiceComponent()来获取的,该方法具体实现是在PackageManagerService.java里面:

可以看到 ComonentName 是从一个内部资源文件中获取到的 com.android.internal.R.string.config_systemUIServiceComponent 这个内部可以在以下路径中搜索到

frameworks/base/core/res/res/values/config.xml

具体定义为:

这个 SystemUIService 是在 SystemUI 应用中定义的,所以接下来的流程将转到 SystemUI 应用中来。

小结一下

        framework 中的 SystemServerrun 方法启动了系统所需要的各种服务,其中就包括 SystemUIService。 具体是通过 PackageManagerInternal 获取到 SystemUIService 的配置名称,使用 startServiceAsUser() 来启动。


2.2在 SystemUI 中的流程:

SystemUI 在源码中路径为

frameworks/base/packages/SystemUI/

首先打开 manifest 文件看下 SystemUIService 的配置:

    <application
        android:name=".SystemUIApplication"
        android:persistent="true"
        ...
        android:directBootAware="true"
        tools:replace="android:appComponentFactory"
        android:appComponentFactory=".SystemUIAppComponentFactory">
        ...
        // 省略代码
        <!-- Broadcast receiver that gets the broadcast at boot time and starts
             up everything else.
             TODO: Should have an android:permission attribute
             -->
        <service android:name="SystemUIService"
            android:exported="true"
        />
    ...

这里我们知道了两个信息:

1.SystemUI 的入口为 SystemUIApplication

2.SystemUIpersistent 应用,即使发生了 crash 系统依然会拉起这个应用

SystemUIApplication:

查看 onCreate 方法:

@Override
public void onCreate() {
    super.onCreate();
    Log.v(TAG, "SystemUIApplication created.");

    // This line is used to setup Dagger's dependency injection and should be kept at the
    // top of this method.        
    TimingsTraceLog log = new TimingsTraceLog("SystemUIBootTiming",Trace.TRACE_TAG_APP);
    log.traceBegin("DependencyInjection");
    mContextAvailableCallback.onContextAvailable(this);
    mRootComponent = SystemUIFactory.getInstance().getRootComponent();
    mSysUIComponent = SystemUIFactory.getInstance().getSysUIComponent();
    mComponentHelper = mSysUIComponent.getContextComponentHelper();

    mBootCompleteCache = mSysUIComponent.provideBootCacheImpl();
    ... // 省略代码

    if (Process.myUserHandle().equals(UserHandle.SYSTEM)) {
        // 一般情况下走这里来,例如开关机启动系统
        IntentFilter bootCompletedFilter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
        bootCompletedFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);

        ... // 省略代码
        registerReceiver(new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    if (mBootCompleteCache.isBootComplete()) return;
                    if (DEBUG) Log.v(TAG, "BOOT_COMPLETED received");
                    unregisterReceiver(this);

                    mBootCompleteCache.setBootComplete();
                    if (mServicesStarted) {
                        final int N = mServices.length;
                        for (int i = 0; i < N; i++) {
                            mServices[i].onBootCompleted();
                        }
                    }

                }
            }, bootCompletedFilter);            
            IntentFilter localeChangedFilter = new IntentFilter(Intent.ACTION_LOCALE_CHANGED);
            registerReceiver(new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    if (Intent.ACTION_LOCALE_CHANGED.equals(intent.getAction())) {
                        if (!mBootCompleteCache.isBootComplete()) return;
                        // Update names of SystemUi notification channels                        
                        NotificationChannels.createAll(context);
                    }
                }
            }, localeChangedFilter);
        } else {
            // We don't need to startServices for sub-process that is doing some tasks.
            // (screenshots, sweetsweetdesserts or tuner ..)            
            // 多用户使用走这里
            ... // 省略代码
            startSecondaryUserServicesIfNeeded();
        }  
    }

对于Android系统来说,当一个应用启动,系统会保证其Application类是第一个被实例化的类,并且Application的onCreate方法,一定先于应用中所有的Activity,Service和BroadcastReceiver的创建。

SystemUI中,SystemUIApplication就是第一个被实例化的类。

在其中,定义了两组服务

  • 一类是所有用户共用的SystemUI服务,例如:Status Bar
  • 一类是每个用户独有的服务

在SystemUIApplication中,onCreate方法被调用:主要注册一个广播接收器,用以接收BOOT_COMPLETED广播,在接收到广播后,调用各模块的函数onBootCompleted。

当SystemApplication家的onCreate执行完毕,就会去启动这个SystemUIService。此服务onCreate方法在启动时被调用。

SystemUIService:

这家伙只是个中转代理(给别人一个启动你的机会)而已,整个服务,真正干活的只有红框中的一句话。调用的是SystemUIApplication中的startServicesIfNeeded方法,转了一圈又回来了。

 再次跳转到 SystemUIApplication 中:

 同样地,在以下路径可以找到所有的 SystemUI 组件定义

frameworks/base/packages/SystemUI/res/values/config.xml

这个是 SystemUI 组件,这里定义了各个组件的类信息:

最终会执行到 startServicesIfNeeded(names) 带参数的方法里面,就是通过反射将各个组件构造后存在 mServices 数组里面。 mServices 是在 SystemUIApplication 中定义的,它保存了所有启动的组件。

在startServicesIfNeeded()会进行遍历来创建SystemUI子类对象,然后将实例赋值给mServices数组,接着执行start()方法,最后执行onBootCompleted();

小结一下

        SystemServer 启动 SystemUIService 之后,就进入到了应用层中,SystemUIApplicationSystemUI 的入口,在 onCreate 方法中做了一些初始化工作,注册监听通知等操作;如果是多用户则会启动了一个组件 NotificationChannels;然后就进入到 SystemUIService 中,它在 onCreate 方法中也是执行了 SystemUIApplication 中的 startServicesIfNeeded() 方法,并把所有的服务都存在 mServices 数组中。


SystemUI 是一个 persistent 应用,它由操作系统启动,主要流程为:

1.Android 系统在开机后会创建 SystemServer 进程,它会启动各种系统所需要的服务,其中就包括 SystemUIService

2.SystemUIService 启动后进入到应用层 SystemUI 中,在 SystemUIApplication 它首先会初始化监听boot completed 等通知,待系统完成启动后会通知各个组件 onBootCompleted

3.在进入 SystemUIService 中依然执行的 SystemUIApplication 中的startServicesIfNeeded() 无参方法启动所有 SystemUI 中的组件。

4.最终的服务启动逻辑都是在 SystemUIApplication 里面,并且都保存在 mServices 数组中。

        以上就是SystemUI进程启动的主要流程,SystemUI相关的子类进行各种逻辑初始化处理都是在start()及onBootCompleted()里面进行。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值