This process is based on Android 9.0

1. Start the SystemUIService

In SystemServer, there is a method called startSystemUi. When the system starts, the startSystemUi() method of SystemServer is executed. It is in this method that SystemUIService is started.

static final void startSystemUi(Context context, WindowManagerService windowManager) {
    Intent intent = new Intent();
    / / specifies the systemui package name "com. Android. Systemui", specifies the class name of the ServiceUIService "com. Android. Systemui. SystemUIService"
    intent.setComponent(new ComponentName("com.android.systemui"."com.android.systemui.SystemUIService"));
    intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
    //Slog.d(TAG, "Starting service: " + intent);
    context.startServiceAsUser(intent, UserHandle.SYSTEM);
    windowManager.onSystemUiStarted();
}
Copy the code

2. Start the SystemUI service in SystemUIService

SystemUIService.java

@Override
public void onCreate(a) {
    super.onCreate();
    // Call SystemUIApplication's startServicesIfNeeded in the onCreate method to start the service
    ((SystemUIApplication) getApplication()).startServicesIfNeeded();

    // code...
}
Copy the code

SystemUIApplication

/** * Makes sure that all the SystemUI services are running. If they are already running, this is a * no-op. This is needed to conditinally start all the services, as we only need to have it in * the main process. * 

This method must only be called from the main thread.

*/
public void startServicesIfNeeded(a) { String[] names = getResources().getStringArray(R.array.config_systemUIServiceComponents); startServicesIfNeeded(names); } Copy the code

Note that the names of the service are read from the config file as follows, which contains the path to SystemBars:

<! -- SystemUI Services: The classes of the stuff to start. -->
<string-array name="config_systemUIServiceComponents" translatable="false">
    <item>com.android.systemui.Dependency</item>
    <item>com.android.systemui.util.NotificationChannels</item>
    <item>com.android.systemui.statusbar.CommandQueue$CommandQueueStart</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.stackdivider.Divider</item>
    <item>com.android.systemui.SystemBars</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.pip.PipUI</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.fingerprint.FingerprintDialogImpl</item>
    <item>com.android.systemui.SliceBroadcastRelayHandler</item>
</string-array>
Copy the code

Specific startup process

private void startServicesIfNeeded(String[] services) {
    If the Boolean variable mServicesStarted is true, the service has been started, and the following startup process is not needed
    if (mServicesStarted) {
        return;
    }
    // Define an array to start SystemUI services that inherit from SystemUI
    mServices = new SystemUI[services.length];

    if(! mBootCompleted) {// check to see if maybe it was already completed long before we began
        // see ActivityManagerService.finishBooting()
        if ("1".equals(SystemProperties.get("sys.boot_completed"))) {
            mBootCompleted = true;
            if (DEBUG) Log.v(TAG, "BOOT_COMPLETED was already sent");
        }
    }

    Log.v(TAG, "Starting SystemUI services for user " +
            Process.myUserHandle().getIdentifier() + ".");
    TimingsTraceLog log = new TimingsTraceLog("SystemUIBootTiming",
            Trace.TRACE_TAG_APP);
    log.traceBegin("StartServices");
    final int N = services.length;
    // Start all the services through traversal
    for (int i = 0; i < N; i++) {
        String clsName = services[i];
        if (DEBUG) Log.d(TAG, "loading: " + clsName);
        log.traceBegin("StartServices" + clsName);
        long ti = System.currentTimeMillis();
        Class cls;
        try {
            cls = Class.forName(clsName);
            mServices[i] = (SystemUI) cls.newInstance();
        } catch(ClassNotFoundException ex){
            throw new RuntimeException(ex);
        } catch (IllegalAccessException ex) {
            throw new RuntimeException(ex);
        } catch (InstantiationException ex) {
            throw new RuntimeException(ex);
        }

        mServices[i].mContext = this;
        mServices[i].mComponents = mComponents;
        if (DEBUG) Log.d(TAG, "running: " + mServices[i]);
        // Call the overridden start() method of each service
        mServices[i].start();
        log.traceEnd();

        // Warn if initialization of component takes too long
        ti = System.currentTimeMillis() - ti;
        if (ti > 1000) {
            Log.w(TAG, "Initialization of " + cls.getName() + " took " + ti + " ms");
        }
        if(mBootCompleted) { mServices[i].onBootCompleted(); }}// code...

    // After starting once, set mServicesStarted to true to avoid repeated startup
    mServicesStarted = true;
}
Copy the code

3. Start StatusBar in SystemBars

The comment on the SystemBars class reads, “Use an in-process implementation to ensure that a Status Bar service is always running, depending on the product configuration.”

/**
 * Ensure a single status bar service implementation is running at all times, using the in-process
 * implementation according to the product config.
 */
Copy the code

So how does the Status Bar get started? In SystemUIApplication, statusbar is started in SystemBars by calling start().

@Override
public void start(a) {
    if (DEBUG) Log.d(TAG, "start");
    createStatusBarFromConfig();
}
Copy the code
private void createStatusBarFromConfig(a) {
    if (DEBUG) Log.d(TAG, "createStatusBarFromConfig");
    final String clsName = mContext.getString(R.string.config_statusBarComponent);
    if (clsName == null || clsName.length() == 0) {
        throw andLog("No status bar component configured".null); } Class<? > cls =null;
    try {
        cls = mContext.getClassLoader().loadClass(clsName);
    } catch (Throwable t) {
        throw andLog("Error loading status bar component: " + clsName, t);
    }
    try {
        mStatusBar = (SystemUI) cls.newInstance();
    } catch (Throwable t) {
        throw andLog("Error creating status bar component: " + clsName, t);
    }
    mStatusBar.mContext = mContext;
    mStatusBar.mComponents = mComponents;
    mStatusBar.start();
    if (DEBUG) Log.d(TAG, "started " + mStatusBar.getClass().getSimpleName());
}
Copy the code

Here, clsName is read from config like names for the previous service, and is the classpath of the StatusBar.

<! -- Component to be used as the status bar service. Must implement the IStatusBar interface. This name is in the ComponentName flattened format (package/class) -->
<string name="config_statusBarComponent" translatable="false">com.android.systemui.statusbar.phone.StatusBar</string>
Copy the code

In this way, you start up an always-running StatusBar service.