This article is based on Android 9.0, code repository address: Android_9.0.0_r45

Article source link:

SystemServer.java

SystemServiceManager.java

SystemService.java

First of all, let’s review the previous article on the Java world of Pangu and Nuwa — Zygote, mainly introduced the Android world’s first Java process Zygote, its main workflow is as follows:

  1. registerServerSocketFromEnv()Registers the server socket for communicating with the client process
  2. preload(), preloads a series of resources to improve application startup speed
  3. forkSystemServer()To createsystem_serverprocess
  4. Retire with success, callrunSelectLoop()Wait for a response to a client request to create an application process

The main process in this article, system_server, is the first process fork from Zygote and is responsible for managing and starting the entire Framework layer.

Take a look at Gityuan’s image again and find the location of the System Server, which hosts the creation and startup of various System services. The system_server process creation process is described in detail in the previous article. Here is a brief flow chart:

The systemServer.main () method is eventually called. Here is a starting point for a detailed analysis of what SystemServer does.

SystemServer Startup process

public static void main(String[] args) {
    new SystemServer().run();
}
Copy the code

Now look at the run() method.

private void run(a) {
    try{...// If the device is older than 1970, many apis will crash when handling negative numbers. So I just set it to January 1, 1970
        if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
            Slog.w(TAG, "System clock is before 1970; setting to 1970.");
            SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
        }

        // If the time zone is not set, the GMT is set by default
        String timezoneProperty =  SystemProperties.get("persist.sys.timezone");
        if (timezoneProperty == null || timezoneProperty.isEmpty()) {
            Slog.w(TAG, "Timezone not set; setting to GMT.");
            SystemProperties.set("persist.sys.timezone"."GMT");
        }

        // Language locale Settings
        if(! SystemProperties.get("persist.sys.language").isEmpty()) {
            final String languageTag = Locale.getDefault().toLanguageTag();

            SystemProperties.set("persist.sys.locale", languageTag);
            SystemProperties.set("persist.sys.language"."");
            SystemProperties.set("persist.sys.country"."");
            SystemProperties.set("persist.sys.localevar"."");
        }

        // The system server should never make non-oneway calls
        Binder.setWarnOnBlocking(true);
        // The system server should always load safe labels
        PackageItemInfo.setForceSafeLabels(true);

        // Default to FULL within the system server.
        SQLiteGlobal.sDefaultSyncMode = SQLiteGlobal.SYNC_MODE_FULL;

        // Deactivate SQLiteCompatibilityWalFlags until settings provider is initialized
        SQLiteCompatibilityWalFlags.init(null);

        // Here we go!
        Slog.i(TAG, "Entered the Android system server!");
        int uptimeMillis = (int) SystemClock.elapsedRealtime();
        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, uptimeMillis);
        if(! mRuntimeRestart) { MetricsLogger.histogram(null."boot_system_server_init", uptimeMillis);
        }

        // Set the vm runtime path
        SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());

        // Mmmmmm... more memory!
        // Clear the vm memory growth limit to allow applications to apply for more memory
        VMRuntime.getRuntime().clearGrowthLimit();

        // Set the effective utilization of heap memory to 0.8, (which may be ignored)
        VMRuntime.getRuntime().setTargetHeapUtilization(0.8 f);

        // Make sure fingerprint information is defined
        Build.ensureFingerprintProperty();

        // Within the system server, it is an error to access Environment paths without
        // explicitly specifying a user.
        Environment.setUserRequired(true);

        // Within the system server, any incoming Bundles should be defused
        // to avoid throwing BadParcelableException.
        BaseBundle.setShouldDefuse(true);

        // Within the system server, when parceling exceptions, include the stack trace
        Parcel.setStackTraceParceling(true);

        // Make sure the system's Binder calls always run at foreground priority
        BinderInternal.disableBackgroundScheduling(true);

        // Increase the number of binder threads in system_server
        BinderInternal.setMaxThreads(sMaxBinderThreads);

        // Prepare the main looper thread (this thread).
        android.os.Process.setThreadPriority(
            android.os.Process.THREAD_PRIORITY_FOREGROUND);
            android.os.Process.setCanSelfBackground(false);
        // 1. Create the main thread Looper
        Looper.prepareMainLooper();
        Looper.getMainLooper().setSlowLogThresholdMs(
                SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);

        // Initialize the native service and load libandroid_servers.so
        System.loadLibrary("android_servers");

        // Check whether the last shutdown failed, there may be no return value
        performPendingShutdown();

        // 2. Initialize system context
        createSystemContext();

        // 3. Create SystemServiceManager
        // Register mSystemServiceManager with sLocalServiceObjects
        mSystemServiceManager = new SystemServiceManager(mSystemContext);
        mSystemServiceManager.setStartInfo(mRuntimeRestart,
                mRuntimeStartElapsedTime, mRuntimeStartUptime);
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
        // Prepare the thread pool for init tasks that can be parallelized
        SystemServerInitThreadPool.get();
    } finally {
        traceEnd();  // InitBeforeStartServices
    }

    // Start services.
    try {
        traceBeginAndSlog("StartServices");
        startBootstrapServices(); // 4. Start the boot service
        startCoreServices();      // 5. Start core services
        startOtherServices();     // 6. Start other services
        SystemServerInitThreadPool.shutdown();
    } catch (Throwable ex) {
        Slog.e("System"."* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *");
        Slog.e("System"."************ Failure starting system services", ex);
        throw ex;
    } finally {
        traceEnd();
    }

    StrictMode.initVmDefaults(null);

    if(! mRuntimeRestart && ! isFirstBootOrUpgrade()) {int uptimeMillis = (int) SystemClock.elapsedRealtime();
        MetricsLogger.histogram(null."boot_system_server_ready", uptimeMillis);
        final int MAX_UPTIME_MILLIS = 60 * 1000;
        if (uptimeMillis > MAX_UPTIME_MILLIS) {
            Slog.wtf(SYSTEM_SERVER_TIMING_TAG,
                    "SystemServer init took too long. uptimeMillis="+ uptimeMillis); }}// 7. Loop forever.
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}
Copy the code

The code is longer, but the logic is clear. I’ve highlighted the seven most important steps in the comments, and I’m going through them one by one.

Looper.prepareMainLooper()

Initialize Looper. For an in-depth understanding of the Handler messaging mechanism, read my other article. Looper.loop() is finally called to open the message loop and begin processing the message.

createSystemContext()

private void createSystemContext(a) {
    // Create system_server context information
    ActivityThread activityThread = ActivityThread.systemMain();
    mSystemContext = activityThread.getSystemContext();
    mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);

    final Context systemUiContext = activityThread.getSystemUiContext();
    // Set the theme for the system dialog, etc
    systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}
Copy the code

Create the system context. First call ActivityThread. SystemMain () method to obtain ActivityThread object, and then obtain the context.

public static ActivityThread systemMain(a) {
    // Do not enable hardware acceleration on low-memory devices
    if(! ActivityManager.isHighEndGfx()) { ThreadedRenderer.disable(true);
    } else {
        ThreadedRenderer.enableForegroundTrimming();
    }
    ActivityThread thread = new ActivityThread();
    thread.attach(true.0);
    return thread;
}
Copy the code

The ActivityThread.attach() method won’t be analyzed here, but will be explained later when the application starts.

Once the system context is created, it’s time to start the various system services. The source code broadly divides services into three categories, to review:

startBootstrapServices(); // 4. Start the boot service
startCoreServices();      // 5. Start core services
startOtherServices();     // 6. Start other services
Copy the code

Analyze one by one.

startBootstrapServices()

private void startBootstrapServices(a) {
    final String TAG_SYSTEM_CONFIG = "ReadingSystemConfig";
    SystemServerInitThreadPool.get().submit(SystemConfig::getInstance, TAG_SYSTEM_CONFIG);

    // Block waiting to establish socket channel with instalLD
    Installer installer = mSystemServiceManager.startService(Installer.class);

    / / start DeviceIdentifiersPolicyService, before ActivityManagerService
    mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);

    // Start ActivityManagerService
    mActivityManagerService = mSystemServiceManager.startService(
            ActivityManagerService.Lifecycle.class).getService();
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
    mActivityManagerService.setInstaller(installer);

    // Start the service PowerManagerService
    mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);

    // Now that the power manager has been started, let the activity manager
    // initialize power management features.
    mActivityManagerService.initPowerManagement();

    // Start the service RecoverySystemService
    mSystemServiceManager.startService(RecoverySystemService.class);

    // Now that we have the bare essentials of the OS up and running, take
    // note that we just booted, which might send out a rescue party if
    // we're stuck in a runtime restart loop.
    RescueParty.noteBoot(mSystemContext);

    // Start LightsService
    mSystemServiceManager.startService(LightsService.class);

    // Package manager isn't started yet; need to use SysProp not hardware feature
    if (SystemProperties.getBoolean("config.enable_sidekick_graphics".false)) {
        mSystemServiceManager.startService(WEAR_SIDEKICK_SERVICE_CLASS);
    }

    // Start DisplayManagerService before PackageManagerService
    mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);

    // We need the default display before we can initialize the package manager.
    mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);

    // Run only the core app while encrypting the device
    String cryptState = SystemProperties.get("vold.decrypt");
    if (ENCRYPTING_STATE.equals(cryptState)) {
        Slog.w(TAG, "Detected encryption in progress - only parsing core apps");
        mOnlyCore = true;
    } else if (ENCRYPTED_STATE.equals(cryptState)) {
        Slog.w(TAG, "Device encrypted - only parsing core apps");
        mOnlyCore = true;
    }

    // Start PackageManagerService
    if(! mRuntimeRestart) { MetricsLogger.histogram(null."boot_package_manager_init_start",
                (int) SystemClock.elapsedRealtime()); } mPackageManagerService = PackageManagerService.main(mSystemContext, installer, mFactoryTestMode ! = FactoryTest.FACTORY_TEST_OFF, mOnlyCore); mFirstBoot = mPackageManagerService.isFirstBoot(); mPackageManager = mSystemContext.getPackageManager();if(! mRuntimeRestart && ! isFirstBootOrUpgrade()) { MetricsLogger.histogram(null."boot_package_manager_init_ready",
                (int) SystemClock.elapsedRealtime());
    }
    if(! mOnlyCore) {boolean disableOtaDexopt = SystemProperties.getBoolean("config.disable_otadexopt".false);
        if(! disableOtaDexopt) { traceBeginAndSlog("StartOtaDexOptService");
            try {
                OtaDexoptService.main(mSystemContext, mPackageManagerService);
            } catch (Throwable e) {
                reportWtf("starting OtaDexOptService", e);
            } finally{ traceEnd(); }}}// Start UserManagerService
    mSystemServiceManager.startService(UserManagerService.LifeCycle.class);

    // Initialize attribute cache to cache package resources
    AttributeCache.init(mSystemContext);

    / / set the AMS
    mActivityManagerService.setSystemProcess();

    // DisplayManagerService needs to setup android.display scheduling related policies
    // since setSystemProcess() would have overridden policies due to setProcessGroup
    mDisplayManagerService.setupSchedulerPolicies();

    // Start OverlayManagerService
    OverlayManagerService overlayManagerService = new OverlayManagerService(
            mSystemContext, installer);
    mSystemServiceManager.startService(overlayManagerService);

    if (SystemProperties.getInt("persist.sys.displayinset.top".0) > 0) {
        // DisplayManager needs the overlay immediately.
        overlayManagerService.updateSystemUiContext();
        LocalServices.getService(DisplayManagerInternal.class).onOverlayChanged();
    }

    // Start SensorService in a separate thread
    mSensorServiceStart = SystemServerInitThreadPool.get().submit(() -> {
        TimingsTraceLog traceLog = new TimingsTraceLog(
                SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
        startSensorService();
    }, START_SENSOR_SERVICE);
}
Copy the code

StartBootstrapServices () method are all key services in the process of system startup and depend on each other. The main services are as follows:

Installer DeviceIdentifiersPolicyService ActivityManagerService PowerManagerService RecoverySystemService LightsService StartSidekickService DisplayManagerService

SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY (100)

PackageManagerService UserManagerService OverlayManagerService SensorService

Twelve core services were launched. PHASE_WAIT_FOR_DEFAULT_DISPLAY, which does not represent a SystemService. Instead, it is an int value of 100. There are other similar ints defined in the SystemService class. Its purpose is to divide the service startup process into phases, each of which has a specific meaning and can do different things. Here is a brief introduction of all the services, and then come back to summarize the stages.

startCoreServices()

private void startCoreServices(a) {
    LightService is required to start BatteryService
    mSystemServiceManager.startService(BatteryService.class);

    // Start UsageStatsService to collect statistics on application usage
    mSystemServiceManager.startService(UsageStatsService.class);
    mActivityManagerService.setUsageStatsManager(
            LocalServices.getService(UsageStatsManagerInternal.class));

    // Check if there is an updatable WebView. Start the service WebViewUpdateService if it exists
    if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
        mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
    }

    // Start BinderCallsStatsService to track CPU consumption for Binder calls
    BinderCallsStatsService.start();
}
Copy the code

Four services are started, BatteryService UsageStatsService WebViewUpdateService and BinderCallsStatsService.

startOtherServices()

StartOtherServices () has more than a thousand lines of source code, like a grocery store, launching a series of services. Let’s simplify the code as much as possible:

KeyAttestationApplicationIdProviderService/KeyChainSystemService
SchedulingPolicyService/TelecomLoaderService/TelephonyRegistry

mContentResolver = context.getContentResolver();

AccountManagerService/ContentService

mActivityManagerService.installSystemProviders();
  
DropBoxManagerService/VibratorService/ConsumerIrService/AlarmManagerService

final Watchdog watchdog = Watchdog.getInstance();
watchdog.init(context, mActivityManagerService);

InputManagerService/WindowManagerService/VrManagerService/BluetoothService
IpConnectivityMetrics/NetworkWatchlistService/PinnerService
InputMethodManagerService/AccessibilityManagerService/StorageManagerService
StorageStatsService/UiModeManagerService/LockSettingsService
PersistentDataBlockService/OemLockService/DeviceIdleController
DevicePolicyManagerService/StatusBarManagerService/ClipboardService
NetworkManagementService/IpSecService/TextServicesManagerService
TextClassificationManagerService/NetworkScoreService/NetworkStatsService
NetworkPolicyManagerService/WifiScanningService/RttService
WifiAware/WifiP2P/Lowpan/Ethernet/ConnectivityService/NsdService
SystemUpdateManagerService/UpdateLockService/NotificationManagerService
DeviceStorageMonitorService/LocationManagerService/CountryDetectorService
SearchManagerService/WallpaperManagerService/AudioService/BroadcastRadioService
DockObserver/ThermalObserver/WiredAccessoryManager/MidiManager/UsbService
SerialService/HardwarePropertiesManagerService/TwilightService
ColorDisplayService/JobSchedulerService/SoundTriggerService/TrustManagerService
BackupManager/AppWidgerService/VoiceRecognitionManager/GestureLauncherService
SensorNotificationService/ContextHubSystemService/DiskStatsService
TimeZoneRulesManagerService/NetworkTimeUpdateService/CommonTimeManagementService
CertBlacklister/EmergencyAffordanceService/DreamManagerService/GraphicsStatsService
CoverageService/PrintManager/CompanionDeviceManager/RestrictionsManagerService
MediaSessionService/MediaUpdateService/HdmiControlService/TvInputManagerService
MediaResourceMonitorService/TvRemoteService/MediaRouterService/FingerprintService
BackgroundDexOptService/PruneInstantAppsJobService/ShortcutService
LauncherAppsService/CrossProfileAppsService/MediaProjectionManagerService
WearConfigService/WearConnectivityService/WearTimeService/WearLeftyService
WearGlobalActionsService/SliceManagerService/CameraServiceProxy/IoTSystemService
MmsServiceBroker/AutoFillService

// It is now time to start up the app processes...
vibrator.systemReady();
lockSettings.systemReady();

/ / 480
mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY); 
/ / 500
mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY); 

wm.systemReady();
mPowerManagerService.systemReady(mActivityManagerService.getAppOpsService());
mPackageManagerService.systemReady();
mDisplayManagerService.systemReady(safeMode, mOnlyCore);

// Start device specific services
final String[] classes = mSystemContext.getResources().getStringArray(
        R.array.config_deviceSpecificSystemServices);
for (final String className : classes) {
    try {
        mSystemServiceManager.startService(className);
    } catch (Throwable e) {
        reportWtf("starting "+ className, e); }}/ / 520
mSystemServiceManager.startBootPhase(SystemService.PHASE_DEVICE_SPECIFIC_SERVICES_READY);

mActivityManagerService.systemReady(() -> {
    / / 550
    mSystemServiceManager.startBootPhase(SystemService.PHASE_ACTIVITY_MANAGER_READY);
    
    startSystemUi(context, windowManagerF);
    
    networkManagementF.systemReady();
    ipSecServiceF.systemReady();
    networkStatsF.systemReady();
    connectivityF.systemReady();
    
    Watchdog.getInstance().start
    mPackageManagerService.waitForAppDataPrepared();

    / / 600
    mSystemServiceManager.startBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
    
    locationF.systemRunning();
    countryDetectorF.systemRunning();
    networkTimeUpdaterF.systemRunning();
    commonTimeMgmtServiceF.systemRunning();
    inputManagerF.systemRunning();
    telephonyRegistryF.systemRunning();
    mediaRouterF.systemRunning();
    mmsServiceF.systemRunning();
    incident.systemRunning();
}
Copy the code

You can see from the above code that quite a few system services are started. The startOtherServices() method goes through five startup phases, as shown below:

SystemService.PHASE_LOCK_SETTINGS_READY             / / 480
SystemService.PHASE_SYSTEM_SERVICES_READY           / / 500
SystemService.PHASE_DEVICE_SPECIFIC_SERVICES_READY  / / 520
SystemService.PHASE_ACTIVITY_MANAGER_READY          / / 550
SystemService.PHASE_THIRD_PARTY_APPS_CAN_START      / / 600
Copy the code

The last call mActivityManagerService. SystemReady () method. In this method, startHomeActivityLocked is called to start the desktop Activity, and the desktop application is started.

Looper.loop()

The system_server process enters the looper.loop () state and waits for other threads to send messages to the main thread via Handler and process them.

SystemServer startup classification

Come back to look at the aforementioned start stage classification, defined in the com. Android. Server SystemService class:

/* * Boot Phases */
public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100; // maybe should be a dependency?

/** * After receiving this boot phase, services can obtain lock settings data. */
public static final int PHASE_LOCK_SETTINGS_READY = 480;

/** * After receiving this boot phase, Services can safely call into core system services * such as the PowerManager or PackageManager. * * after this stage, Can safely call system core services, such as PowerManager and PackageManager */
public static final int PHASE_SYSTEM_SERVICES_READY = 500;

/** * After receiving this boot phase, services can safely call into device specific services. Device-specific services can be safely called */
public static final int PHASE_DEVICE_SPECIFIC_SERVICES_READY = 520;

/** * After receiving this boot phase, services can broadcast Intents. ** After this phase, services can broadcast Intents
public static final int PHASE_ACTIVITY_MANAGER_READY = 550;

/** * After receiving this boot phase, services can start/bind to third party apps. * Apps will be able to make Binder calls into services at this point. * * After this stage, the service can launch/bind third-party applications * the application can then make Binder calls */
public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600;

/** * After receiving this boot phase, services can allow user interaction with the device. * This phase occurs when boot has completed and the home application has started. * System services may prefer to listen to this phase rather than registering a * broadcast Receiver for ACTION_BOOT_COMPLETED to reduce overall latency. * * After this phase, the user is allowed to interact with the device. * This phase occurs when the startup is complete and the home application has started. * System services prefer to listen on this phase rather than on the start broadcast ACTION_BOOT_COMPLETED to reduce latency */
public static final int PHASE_BOOT_COMPLETED = 1000;
Copy the code

The positions of the various stages in the system_server startup process are roughly as follows:

private void startBootstrapServices(a) {.../ / 100mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); . }private void startOtherServices(a) {.../ / 480
    mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
    / / 500mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY); ./ / 520
    mSystemServiceManager.startBootPhase(SystemService.PHASE_DEVICE_SPECIFIC_SERVICES_READY);

    mActivityManagerService.systemReady(() -> {
        mSystemServiceManager.startBootPhase(
                    SystemService.PHASE_ACTIVITY_MANAGER_READY); / / 550. mSystemServiceManager.startBootPhase( SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);/ / 600}}Copy the code

The final systemservice.phase_boot_completed (1000) is called in AMS’s finishBooting() method. Notice also that the 480 and 500 phases are connected, and nothing happens in between.

So, what exactly is the function of compartmentalization? The answer is in the startBootPhase() method:

public void startBootPhase(final int phase) {
    if (phase <= mCurrentPhase) {
        throw new IllegalArgumentException("Next phase must be larger than previous");
    }
    mCurrentPhase = phase;

    try {
        final int serviceLen = mServices.size();
        for (int i = 0; i < serviceLen; i++) {
            final SystemService service = mServices.get(i);
            long time = SystemClock.elapsedRealtime();
            try {
                // Call back the onBootPhase() method of the system service
                service.onBootPhase(mCurrentPhase);
            } catch (Exception ex) {
                throw new RuntimeException("Failed to boot service "
                        + service.getClass().getName()
                        + ": onBootPhase threw an exception during phase "
                        + mCurrentPhase, ex);
            }
            warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onBootPhase"); }}finally{ Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); }}Copy the code

The core is service.onBootPhase(mCurrentPhase); . All system services inherit from SystemService, and the startBootPhase() method calls back the onBootPhase() method of all system services that have been added to mServices in the current phase to do something appropriate at the appropriate phase. Take AMS as an example:

@Override
public void onBootPhase(int phase) {
    mService.mBootPhase = phase;
    if(phase == PHASE_SYSTEM_SERVICES_READY) { mService.mBatteryStatsService.systemServicesReady(); mService.mServices.systemServicesReady(); }}Copy the code

How does SystemServer start services?

Read SystemServer source code, its most important work is to create and start a variety of system services. So how are services typically created? The Installer, the first service created in startBootstrapServices(), is used as an example:

Installer installer = mSystemServiceManager.startService(Installer.class);
Copy the code

Enter the SystemServiceManager startService() method:

public <T extends SystemService> T startService(Class<T> serviceClass) {
    try {
        // Get the service name
        final String name = serviceClass.getName();

        // Create the service.
        if(! SystemService.class.isAssignableFrom(serviceClass)) {throw new RuntimeException("Failed to create " + name
                    + ": service must extend " + SystemService.class.getName());
        }
        final T service;
        try {
            // Get the constructor for the service class
            Constructor<T> constructor = serviceClass.getConstructor(Context.class);
            // reflection creates a service
            service = constructor.newInstance(mContext);
        } catch (InstantiationException ex) {
            throw new RuntimeException("Failed to create service " + name
                    + ": service could not be instantiated", ex);
        } catch (IllegalAccessException ex) {
            throw new RuntimeException("Failed to create service " + name
                    + ": service must have a public constructor with a Context argument", ex);
        } catch (NoSuchMethodException ex) {
            throw new RuntimeException("Failed to create service " + name
                    + ": service must have a public constructor with a Context argument", ex);
        } catch (InvocationTargetException ex) {
            throw new RuntimeException("Failed to create service " + name
                    + ": service constructor threw an exception", ex);
        }

        startService(service);
        return service;
    } finally{ Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); }}Copy the code

Create and start a system service. This system must be com. Android. Server SystemService subclass. Create an example from the reflection of the Class object passed in as the argument, and call the overloaded startService() method:

public void startService(@NonNull final SystemService service) {
    // Register it.
    mServices.add(service);
    // Start it.
    long time = SystemClock.elapsedRealtime();
    try {
        // Call back the system service onStart() method
        service.onStart();
    } catch (RuntimeException ex) {
        throw new RuntimeException("Failed to start service " + service.getClass().getName()
            + ": onStart threw an exception", ex);
    }
    warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
}
Copy the code

Just two steps. The first step is to register the service. MServices is an ArrayList

object that holds the SystemService that has been created. Step 2, call the onStart() method of the service, again using Installer as an example:

@Override
public void onStart(a) {
    if (mIsolated) {
        mInstalld = null;
    } else{ connect(); }}Copy the code

The service is then started. This is a relatively common startup mode, of course, there are some system services have different startup mode, here is not an analysis, later have the opportunity to analyze the specific service to analyze.

conclusion

The SystemServer startup process is straightforward and not so crooked. Here is a brief summary:

  1. Language, time zone, and region Settings
  2. Vm memory Settings
  3. Fingerprint information, Binder call Settings
  4. Looper.prepareMainLooper()Create the main thread Looper
  5. Initialize the Native service and load itlibandroid_servers.so
  6. createSystemContext()To initialize the system context
  7. Create system service managementSystemServiceManager
  8. startBootstrapServicesTo start the system boot service
  9. startCoreServicesTo start core system services
  10. startOtherServicesTo start other services
  11. Looper.loop()To start the message loop

In addition, AMS’s onSystemReady() method is called at the end of startOtherServices to start the desktop Activity.

trailer

Remember the Zygote process’s runSelectLoop() method? After creating the system_server process, Zygote silently waits for the client to request to create the application process. In the next article, we will take a look at how the client sends requests, how Zygote handles requests, and how the application process is created from the source point of view. Stay with us!

This article first published wechat official account: BingxinshuaiTM, focusing on Java, Android original knowledge sharing, LeetCode problem solving.

More latest original articles, scan code to pay attention to me!