SystemUI启动流程及结构框架

前言

本文基于Android15源码对SystemUI启动流程及结构框架进行初步分析。


一、启动流程

启动流程主要包括以下两部分。

1.在Framework中启动SystemUIService

zygote进程启动SystemServer,在run()方法通过startOtherServices启动一系列服务,其中也包括SystemUI相关的服务,主要是在startSystemUi()方法。

frameworks/base/services/java/com/android/server/SystemServer.java

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();
    }

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

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

2.1 SystemUIApplication

由于SystemUI是一个app,其主入口在SystemUIApplication。

frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java

public void onCreate() {
    ...
    mInitializer = mContextAvailableCallback.onContextAvailable(this);
    mSysUIComponent = mInitializer.getSysUIComponent();
    mBootCompleteCache = mSysUIComponent.provideBootCacheImpl();
    ...
    if (mProcessWrapper.isSystemUser()) {
        ...
        IntentFilter bootCompletedFilter = new
                IntentFilter(Intent.ACTION_LOCKED_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++) {
                        notifyBootCompleted(mServices[i]);
                    }
                }
            }
        }, 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 {
        ...
        startSecondaryUserServicesIfNeeded();
    }
}

onCreate()方法主要是做一些初始化工作,如果是系统启动的服务,则进行 boot completed 等通知的注册,然后系统启动完成后,通知到各个组件,如果是在多用户环境下,则通过调用startSecondaryUserServicesIfNeeded()启动一系列的服务。

private void startServicesIfNeeded(
        Map<Class<?>, Provider<CoreStartable>> startables,
        String metricsPrefix,
        String vendorComponent) {
    if (mServicesStarted) {
        return;
    }
    mServices = new CoreStartable[startables.size() + (vendorComponent == null ? 0 : 1)];
    ....
    do {
        startedAny = false;
        queue = nextQueue;
        nextQueue = new ArrayDeque<>(startables.size());

        while (!queue.isEmpty()) {
            Map.Entry<Class<?>, Provider<CoreStartable>> entry = queue.removeFirst();

            Class<?> cls = entry.getKey();
            Set<Class<? extends CoreStartable>> deps =
                    mSysUIComponent.getStartableDependencies().get(cls);
            if (deps == null || startedStartables.containsAll(deps)) {
                String clsName = cls.getName();
                int i = serviceIndex;  // Copied to make lambda happy.
                timeInitialization(
                        clsName,
                        () -> mServices[i] = startStartable(clsName, entry.getValue()),
                        log,
                        metricsPrefix);
                startedStartables.add(cls);
                startedAny = true;
                serviceIndex++;
            } else {
                nextQueue.add(entry);
            }
        }
        numIterations++;
    } while (startedAny && !nextQueue.isEmpty()); // if none were started, stop.
    ...
    mSysUIComponent.getInitController().executePostInitTasks();
    ...
}

startSecondaryUserServicesIfNeeded()通过调用startServicesIfNeeded()构造了一系列服务组件CoreStartable并存在了一个mServices数组里面,执行各个组件的startStartable()方法,这样各个组件就完成了启动工作。

2.2 SystemUIService

SystemUIService是一个关键的服务, 在onCreate()的时候会通过startSystemUserServicesIfNeeded()跳转回SystemUIApplication中的startServicesIfNeeded()方法。

frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIService.java

public void onCreate() {
    super.onCreate();

    // Start all of SystemUI
    ((SystemUIApplication) getApplication()).startSystemUserServicesIfNeeded();

    // Finish initializing dump logic
    mLogBufferFreezer.attach(mBroadcastDispatcher);

    // Attempt to dump all LogBuffers for any uncaught exception
    mUncaughtExceptionPreHandlerManager.registerHandler(
            (thread, throwable) -> mLogBufferEulogizer.record(throwable));

    // If configured, set up a battery notification
    if (getResources().getBoolean(R.bool.config_showNotificationForUnknownBatteryState)) {
        mBatteryStateNotifier.startListening();
    }
    ...
}

3.启动主要流程图

在这里插入图片描述


二、结构框架

SystemUI的整体结构可以拆分成StatusBarWindow和NotificationShadeWindow两大部分。其中StatusBarWindow 是系统顶部的常驻状态栏容器,主要用于显示系统图标(如电池、Wi-Fi、信号强度)、时间、通知图标等,而NotificationShadeWindow 是用户下拉状态栏后展开的面板,包括完整的通知列表和快速设置等。

框架图如下:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值