Android Zygote process startup process, androidzygote

Source: Internet
Author: User

Android Zygote process startup process, androidzygote

Zygote stands for "fertilized eggs". Almost all application processes in the Android system are incubated by Zygote processes, and the Java environment is also created by Zygote, it establishes the environment required for running our app and is the ancestor of the app. Therefore, it is necessary to analyze its startup and internal logic.

Android is based on the Linux kernel. in Linux, all processes are the child processes of the init process. That is to say, all processes are directly or indirectly fork processes. The Zygote process is no exception. It is created by the init process during system startup. In the system startup script system/core/rootdir/init. rc file, we can see the script command to start the Zygote process:

Service zygote/system/bin/app_process-Xzygote/system/bin -- zygote -- start-system-server socket zygote stream 666 # zygote requires a socket onrestart write/sys/android_power/request_state wake # If zygote restarts, you need to perform this operation onrestart write/sys/power/state on onrestart restart media onrestart restart netd

The preceding script indicates that you want to start a process named zygote. the executable file is/system/bin/app_process,--Xzygote /system/bin --zygote --start-system-serverThese are the parameters passed to zygote. For more information about the functions of the rest, see annotations.

The source code of app_process is in the frameworks/base/cmds/app_process directory. The main entry function is in the file app_main.cpp. Next, we will start with this main function to analyze the internal logic of zygote.

Note: The source code analysis in this article is based on Android 4.4.

/** Start zygote by/system/bin/app_process-Xzygote/system/bin -- zygote -- start-system-server *. Therefore, what is stored in argc = 5 * argv is these five parameters argv [0] = "/system/bin/app_process ", argv [1] = "-Xzygote ".... */int main (int argc, char * const argv []) {...... // These are global variables in ProcessState. cpp mArgC = argc; mArgV = argv; mArgLen = 0; for (int I = 0; I <argc; I ++) {mArgLen + = strlen (argv [I]) + 1;} mArgLen --; // use The code above is mainly to save the parameter information to the global variable AppRuntime runtime; const char * argv0 = argv [0]; // Process command line arguments // ignore argv [0] argc --; argv ++; // Everything up to '--' or first non'-'arg goes to the vm int I = runtime. addVmArguments (argc, argv); // This function returns 1, indicating that only the-Xzytote parameter is processed, the so-called processing is actually adding this parameter to the mOptions variable of the runtime object. // Parse runtime arguments. stop at first unrecognized option. bool zygote = false; bool startSystemServer = false; bool application = false; const char * parentDir = NULL; const char * niceName = NULL; const char * className = NULL; // before entering the loop I = 1, argc = 4 argv points to "-Xzygote" while (I <argc) {const char * arg = argv [I ++]; if (! ParentDir) {parentDir = arg; // parentDir is assigned as "/system/bin"} else if (strcmp (arg, "-- zygote") = 0) {zygote = true; niceName = "zygote"; // process name} else if (strcmp (arg, "-- start-system-server") = 0) {startSystemServer = true;} else if (strcmp (arg, "-- application") = 0) {// do not go to this branch application = true;} else if (strncmp (arg, "-- nice-name =", 12) = 0) {// do not go to this branch niceName = arg + 12;} else {// Skip this branch className = arg; break;} if (niceName & * niceName) {// set the process name setArgv0 (argv0, niceName); set_process_name (niceName);} runtime. mParentDir = parentDir; if (zygote) {// take this branch runtime. start ("com. android. internal. OS. zygoteInit ", startSystemServer? "Start-system-server": "");} else if (className) {// Remainder of args get passed to startup class main () runtime. mClassName = className; runtime. mArgC = argc-I; runtime. mArgV = argv + I; runtime. start ("com. android. internal. OS. runtimeInit ", application? "Application": "tool");} else {fprintf (stderr, "Error: no class name or -- zygote supplied. \ n "); app_usage (); LOG_ALWAYS_FATAL (" app_process: no class name or -- zygote supplied. "); return 10 ;}}

The main function is to create a runtime instance, parse the parameters, call the start function of runtime, and then analyze the start function of AppRuntime:

/** Start the Android runtime. this involves starting the virtual machine * and calling the "static void main (String [] args)" method in the class * named by "className ". ** Passes the main function two arguments, the class name and the specified * options string. * /// first, we need to specify the next parameter className = "com. android. internal. OS. zygoteInit "options =" start-system-server "void AndroidRuntime: start (const Char * className, const char * options) {ALOGD ("\ n >>>>> AndroidRuntime START % s <\ n", className! = NULL? ClassName: "(unknown)");/** 'startsystemserver = true' means runtime is obsolete and not run from * init. rc anymore, so we print out the boot start event here. */if (strcmp (options, "start-system-server") = 0) {/* track our progress through the boot sequence */const int LOG_BOOT_PROGRESS_START = 3000; LOG_EVENT_LONG (LOG_BOOT_PROGRESS_START, ns2ms (systemTime (SYSTEM_TIME_MONOTONIC);} cons T char * rootDir = getenv ("ANDROID_ROOT"); if (rootDir = NULL) {rootDir = "/system"; if (! HasDir ("/system") {LOG_FATAL ("No root directory specified, and/android does not exist. "); return;} setenv (" ANDROID_ROOT ", rootDir, 1); // configure the ANDROID_ROOT environment variable} // const char * kernelHack = getenv (" LD_ASSUME_KERNEL "); // ALOGD ("Found LD_ASSUME_KERNEL = '% s' \ n", kernelHack);/* start the virtual machine */JniInvocation jni_invocation; jni_invocation.Init (NULL); JNIEnv * env; if (startVm (& mJavaVM, & env)! = 0) {// create a virtual machine return;} onVmCreated (env);/** Register android functions. */if (starregulatory (env) <0) {ALOGE ("Unable to register all android natives \ n"); return;}/** We want to call main () with a String array with arguments in it. * At present we have two arguments, the class name and an option string. * Create an array to hold them. */jclass stringClass; jobjectArray strArray; jstring classN AmeStr; jstring optionsStr; stringClass = env-> FindClass ("java/lang/String"); assert (stringClass! = NULL); strArray = env-> NewObjectArray (2, stringClass, NULL); assert (strArray! = NULL); classNameStr = env-> NewStringUTF (className); assert (classNameStr! = NULL); env-> SetObjectArrayElement (strArray, 0, classNameStr); optionsStr = env-> NewStringUTF (options); env-> SetObjectArrayElement (strArray, 1, optionsStr ); /** Start VM. this thread becomes the main thread of the VM, and will * not return until the VM exits. */char * slashClassName = toSlashClassName (className); jclass startClass = env-> FindClass (slashClassName); if (startClass = NULL) {ALOGE ("JavaVM unable to locate class '% s' \ n", slashClassName);/* keep going */} else {jmethodID startMeth = env-> GetStaticMethodID (startClass, "main ", "([Ljava/lang/String;) V"); if (startMeth = NULL) {ALOGE ("JavaVM unable to find main () in '% s' \ n ", className);/* keep going */} else {/* Call com. android. internal. OS. the main function of ZygoteInit. strArray is a parameter. The array contains two elements, className = "com. android. internal. OS. zygote Init "options =" start-system-server "*/env-> CallStaticVoidMethod (startClass, startMeth, strArray); # if 0 if (env-> ExceptionCheck ()) threadExitUncaughtException (env); # endif} free (slashClassName); ALOGD ("Shutting down VM \ n"); if (mJavaVM-> DetachCurrentThread ()! = JNI_ OK) ALOGW ("Warning: unable to detach main thread \ n"); if (mJavaVM-> DestroyJavaVM ()! = 0) ALOGW ("Warning: VM did not shut down cleanly \ n ");}

The start function mainly performs the following tasks:

  1. Call the startVm function to create a VM;
  2. Call the starregulatory function to register the Android Natvie function;
  3. Let the VM execute the main function of com. android. internal. OS. ZygoteInit.

Next we will analyze the main function of com. android. internal. OS. ZygoteInit, create a VM, and register the native function.

Public static void main (String argv []) {try {// Start profiling the zygote initialization. samplingProfilerIntegration. start (); registerZygoteSocket (); // 1. Create a socket for listening to the EventLog of the fork request sent by ams. writeEvent (LOG_BOOT_PROGRESS_PRELOAD_START, SystemClock. uptimeMillis (); preload (); // 2. Load classes and resources. EventLog will be analyzed in detail later. writeEvent (LOG_BOOT_PROGRESS_PRELOAD_END, SystemClock. uptimeMillis (); // Finis H profiling the zygote initialization. samplingProfilerIntegration. writeZygoteSnapshot (); // Do an initial gc to clean up after startup gc (); // If requested, start system server directly from Zygote if (argv. length! = 2) {throw new RuntimeException (argv [0] + USAGE_STRING);} if (argv [1]. equals ("start-system-server") {startSystemServer (); // 3. Create a system server process, ams wms pms and other common services are in this process} else if (! Argv [1]. equals ("") {throw new RuntimeException (argv [0] + USAGE_STRING);} Log. I (TAG, "Accepting command socket connections"); if (ZYGOTE_FORK_MODE) {runForkMode () ;}else {runSelectLoopMode (); // 4. Enter the loop listening mode, listening for external requests} closeServerSocket ();} catch (MethodAndArgsCaller caller) {caller. run ();} catch (RuntimeException ex) {Log. e (TAG, "Zygote died with exception", ex); closeServerSocket (); throw ex ;}}

The main function of com. android. internal. OS. ZygoteInit mainly performs the following four tasks:

  1. Call registerZygoteSocket () to create a socket for listening to the fork requests sent by ams;
  2. Call preload () to pre-load classes and resources;
  3. Call startSystemServer () to create a system server process. Common services such as ams wms pms are in this process;
  4. Call runSelectLoopMode () to go To the loop listening mode and listen to external requests.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.