Overview of Zygote

The Zygote process is the first process on the Android level (the first ART virtual machine), commonly known as the process incubator, all processes in Android are fork (Zygote). The main way to communicate with SystemServer is through socket. The main responsibilities are:

  • Preload common classes, Drawable and Color resources, openGL and shared libraries, and WebViews
  • Example Create the system_server process
  • Create socket, runSelectLoop infinite loop, to receive system_server create process command, to split the process

Who created the Zygote process

The Android operating system is based on the Linux operating system. On the Android operating system, Linux creates the first user-space process init process when booting up. There’s a lot of initialization going on in the init process, and the job of the init process is to parse the init.rc file and initialize a lot of services

Init Process Specifies the function of the process

  1. Create and mount the file directory required for startup
  2. Initialize and start property services, such as service_manager: a daemon for Binder IPC communication and a Binder service in its own right. The ServiceManager process starts Binder to query and register services
  3. Parse the init.rc file and start Zygote

Zygote code tracks Android28

It is executed when the Zygote process is created/frameworks/base/cmds/app_process/app_main.cppThe following code loads the zygoteinit. Java and RuntimelNit. Java classes.Then we look at the main method of the zygoteinit.java file, the following code is not all of the code, I just copied a few key points

 public static void main(String argv[]) {
 	// Create ZygoteServer. ZygoteServer is used to create sockets that accept commands to fork child processes
    ZygoteServer zygoteServer = new ZygoteServer();
    
    // Tell the JVM that Zygote is about to be created
     ZygoteHooks.startZygoteNoThreadCreation();
    / / open DDMS
    RuntimeInit.enableDdms();
   
   // Whether to start the SystemServer process
    boolean startSystemServer = false;
    
   // Is a command to make Zygote lazy to load some resources
   boolean enableLazyPreload = false;
    for (int i = 1; i < argv.length; i++) {
    	// Is the command to start SystemServer
        if ("start-system-server".equals(argv[i])) {
            startSystemServer = true;
        }else if ("--enable-lazy-preload".equals(argv[i])) {
                    enableLazyPreload = true;
        }
        / /...
    }
    
    // Register a Socket listener to receive commands to fork a child process
    zygoteServer.registerServerSocketFromEnv(socketName);
    // In some configurations, we avoid preloading resources and classes eagerly.
    // In such cases, we will preload things prior to our first fork.
    // There are cases where classes and resources need to be preloaded
    if(! enableLazyPreload) { bootTimingsTraceLog.traceBegin("ZygotePreload");
        EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
            SystemClock.uptimeMillis());
        // preload the /system/etc/ preload-classes class
        // Preload resource images and colors
       // Preload OpenGL, etc
        preload(bootTimingsTraceLog);
        EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
            SystemClock.uptimeMillis());
        bootTimingsTraceLog.traceEnd(); // ZygotePreload
    } else {
        Zygote.resetNicePriority();
    }
    
    / / execution System. The gc ();
    gcAndFinalize();
    
    // Access security
    Zygote.nativeSecurityInit() 
    // Sandbox storage
    Zygote.nativeUnmountStorageOnInit();
    
    // Tell the virtual machine it is ready to create threads in the zygote process
    ZygoteHooks.stopZygoteNoThreadCreation();
    
    // fork SystemServer
    if (startSystemServer) {
        Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
        // child (system_server) process.
        if(r ! =null) {
            r.run();
            return; }}// The socket enters the wireless loop to receive the command to create the process
    caller = zygoteServer.runSelectLoop(abiList);
Copy the code

Then look at the two main methods in Zygote

  • ForkAndSpecialize ():fork a new process
  • ForkSystemServer (): Forks out the SystemServer process

Why Zygote uses sockets instead of binder mechanisms?

Forks are restricted by rules and are not allowed in multithreaded programs. Binder’s mechanism, however, is based on multithreading. reference

2: SystemServer

Service process: Zygote is the first process to split from Zygote. Many important Android services, such as ActivityManagerService, PackageManagerService, WindowManagerService, and so on, are started here.

SystemServer code

SystemServer. The main entrance

/ / the entry
public static void main(String[] args) {
    new SystemServer().run();
}
private void run(a) {
    try {
       	 traceBeginAndSlog("InitBeforeStartServices");
            // If a device's clock is before 1970 (before 0), a lot of
            // APIs crash dealing with negative numbers, notably
            // java.io.File#setLastModified, so instead we fake it and
            // hope that time from cell towers or NTP fixes it shortly.
            if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
                Slog.w(TAG, "System clock is before 1970; setting to 1970.");
                SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
            }

            //
            // Default the timezone property to GMT if not set.
            //
            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");
            }

            // If the system has "persist.sys.language" and friends set, replace them with
            // "persist.sys.locale". Note that the default locale at this point is calculated
            // using the "-Duser.locale" command line flag. That flag is usually populated by
            // AndroidRuntime using the same set of system properties, but only the system_server
            // and system apps are allowed to set them.
            //
            // NOTE: Most changes made here will need an equivalent change to
            // core/jni/AndroidRuntime.cpp
            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);
            // 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);
            }

            // In case the runtime switched since last boot (such as when
            // the old runtime was removed in an OTA), set the system
            // property so that it is in sync. We can | xq oqi't do this in
            // libnativehelper's JniInvocation::Init code where we already
            // had to fallback to a different runtime because it is
            // running as root and we need to be the system user to set
            // the property. http://b/11463182
            SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());

            // Mmmmmm... more memory!
            VMRuntime.getRuntime().clearGrowthLimit();

            // The system server has to run all of the time, so it needs to be
            // as efficient as possible with its memory usage.
            VMRuntime.getRuntime().setTargetHeapUtilization(0.8 f);

            // Some devices rely on runtime fingerprint generation, so make sure
            // we've defined it before booting further.
            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);

            // Ensure binder calls into the system 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);
        // Set the primary Looper of the SystemServer thread
        Looper.prepareMainLooper();
        Looper.getMainLooper().setSlowLogThresholdMs(
                SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);

        // Initialize native services.
        System.loadLibrary("android_servers");

      
        // Initialize the system context.
        // Initialize SystemContext
        createSystemContext();

        // Create the system service manager.
        // Create SystemServiceManager, we can use SystemServiceManager to get various xxServiceManager
        mSystemServiceManager = new SystemServiceManager(mSystemContext);
        mSystemServiceManager.setStartInfo(mRuntimeRestart,
                mRuntimeStartElapsedTime, mRuntimeStartUptime);
         / / the SystemServiceManager. The class to add to LocalServices inside
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
    } finally{}// Start various services
    try {
        
        startBootstrapServices();
        startCoreServices();
        startOtherServices();
        SystemServerInitThreadPool.shutdown();
    } catch (Throwable ex) {
      
    }

    StrictMode.initVmDefaults(null);
    // Loop forever.
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}
Copy the code

Initialize the necessary environment parameters, such as system time, time zone, language, load some libraries, initialize Looper, etc., as well as create SystemServiceManager to start and manage the system services

Let’s look at the createSystemContext() method

Private void createSystemContext() {//ActivityThread is each Android entry class ActivityThread ActivityThread = ActivityThread.systemMain(); mSystemContext = activityThread.getSystemContext(); mSystemContext.setTheme(DEFAULT_SYSTEM_THEME); final Context systemUiContext = activityThread.getSystemUiContext(); systemUiContext.setTheme(DEFAULT_SYSTEM_THEME); }Copy the code

Create ActivityThread in SystemServer. In fact, SystemServer is not only a background process, but also a process that runs component services. Many dialog boxes are displayed in SystemServer. Activitythreads are created in the SystemServer process, which is different from normal processes. Attach () = attach(); attach() = attach(); attach() = attach()

Now look at the start startBootstrapServices() method

This main startup system must be the party services, such as AMS, PMS, DispalyMangerService, WMS. Wait, how do you start these services

private void startBootstrapServices() { mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class); / / initialize the AMS mActivityManagerService = mSystemServiceManager startService ( ActivityManagerService.Lifecycle.class).getService(); mActivityManagerService.setSystemServiceManager(mSystemServiceManager); mActivityManagerService.setInstaller(installer); } / / initialization PowerManagerService mPowerManagerService = mSystemServiceManager. StartService (PowerManagerService. Class); / / initialize LightsService mSystemServiceManager. StartService (LightsService. Class); / / initialize DisplayManagerService mDisplayManagerService = mSystemServiceManager. StartService (DisplayManagerService. Class); / / initialize PackageManagerService mPackageManagerService = PackageManagerService. Main (mSystemContext, installer, mFactoryTestMode ! = FactoryTest.FACTORY_TEST_OFF, mOnlyCore); mFirstBoot = mPackageManagerService.isFirstBoot();Copy the code

reference

What process does an APP go through from startup to home page display? Zygote process start process SystemServer process analysis