Android source code Analysis--zygote Process Analysis

Source: Internet
Author: User
Tags strcmp

As we all know, there are two completely different worlds in the Android system:
1. In the Java world, the SDK provided by Google is primarily aimed at the world, and the programs running in this world are Java programs based on Dalvik virtual machines.
2. Native world, which is a program developed using the C or C + + language.

So the question is, how does the Android system relate the two worlds, which is related to the zygote process described in this blog post. Android is built on the Linux kernel so that Android first enters the native world. The first process initiated by the Linux system is the init process, and the first process started in the Android system is the INIT process, and the Init process then creates the zygote process based on the configuration options in the Init.rc file.

The origin of Zygote's name

The name of the zygote process was initially not "zygote", but "app_process", which was specified in the Android.mk file, but was replaced by a Linux app_process system call during the run to replace the name with " Zygote ". The source file that corresponds to it is app_main.cpp.

App_main.cpp Analysis

(Source location: frameworks\base\cmds\app_process\app_main.cpp)
The method to be executed is APP_ Main.cpp in the main method, the method is relatively simple, it first added some parameters to the virtual machine, then parse the runtime parameters, if our parameters are set to execute the zygote process, the bool value zygote to True, and then call the Start method in Appruntime.

intMainintargcChar*ConstArgv[]) {...//Two global variables are defined in ProcessState.cppMARGC = ARGC;    MARGV = argv; Marglen =0; for(intI=0; i<argc; i++) {Marglen + =strlen(Argv[i]) +1;    } marglen--; 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    inti = runtime.addvmarguments (argc, argv);///Next parse some run-time parameters    BOOLZygote =false;BOOLStartsystemserver =false;BOOLApplication =false;Const Char* Parentdir = NULL;Const Char* Nicename = NULL;Const Char* ClassName = NULL; while(I < ARGC) {Const Char* arg = argv[i++];if(!parentdir)        {parentdir = arg; }Else if(strcmp(ARG,"--zygote") ==0) {zygote =true; Nicename ="Zygote"; }Else if(strcmp(ARG,"--start-system-server") ==0) {Startsystemserver =true; }Else if(strcmp(ARG,"--application") ==0) {application =true; }Else if(strncmp(ARG,"--nice-name=", A) ==0) {Nicename = arg + A; }Else{className = arg; Break; }    }if(Nicename && *nicename) {setArgv0 (argv0, nicename);//Change the name of the process here to ZygoteSet_process_name (Nicename); } Runtime.mparentdir = Parentdir;if(zygote) {//Call the Start method of Appruntime to execute the main method of the class named Zygoteinit.         ///argv parameter is "--zygote" "--start-system-server", then Startsystemserver is trueRuntime.start ("Com.android.internal.os.ZygoteInit", Startsystemserver?"Start-system-server":""); }Else if(ClassName)        {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 Ten; }}
Analysis of Start method in Appruntime

In the main method of App_main, we finally go to the Appruntime start method, and then analyze the Start method in Appruntime, and the implementation and definition of the class are all in App_main.cpp.

//Incoming parameter is "Com.android.internal.os.ZygoteInit", "Start-system-server"voidAndroidruntime:: Start(const char*ClassName, const Char*Options) {ALOGD ("\n>>>>>> androidruntime START%s <<<<<<\n", ClassName!= NULL ?ClassName:"(unknown)");/ * * ' startsystemserver = = True ' We print out the boot boot event here * /    if(strcmp (Options,"Start-system-server")== 0) {/* Track our progress through the boot sequence * /const INT Log_boot_progress_start=  the;    Log_event_long (Log_boot_progress_start, ns2ms (SystemTime (system_time_monotonic))); }Set the environment variable if there is no android_root in the environment variableconst 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); }/ * Turn on the virtual machine * /Jniinvocation jni_invocation; Jni_invocation.Init (NULL); JNIEnv*Envif(STARTVM (&MJAVAVM,&Env!= 0) {return; } onvmcreated (env);/ * Register some JNI functions * /    if(Startreg (ENV)< 0) {Aloge ("Unable to register all Android natives\n");return; }/ * * Next, call Zygoteinit's Main method with the JNI call, and set the pass parameter * /Jclass Stringclass;    Jobjectarray Strarray;    Jstring Classnamestr;    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);/ * * This thread will become the primary thread of the virtual machine and accompany the virtual machine always exists * /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 the static Main method in the Java classEnv -Callstaticvoidmethod (Startclass, Startmeth, Strarray);.......} free (slashclassname);......}

Let's summarize the work of the Start method:
1. Setting Android_root Environment variables
2. Call the Startvm method in the Androidruntime class to create a virtual machine
3. Call the Startreg function to register the JNI function
4. Invoking the main method of the Java class Zygoteinit via a JNI call
So far, we have entered the world of Java.

Into the Java World

From the above analysis, our program has come to the Java class Zygoteinit static Main method, the class is defined in the Frameworks\base\core\java\com\android\internal\os\ The Zygoteinit.java. Next we look at her work:

     Public Static void Main(String argv[]) {Try{//Start configuring the initialization of the zygote processSamplingprofilerintegration.start ();//Establish the service side of IPC communicationRegisterzygotesocket (); Eventlog.writeevent (Log_boot_progress_preload_start, Systemclock.uptimemillis ());//Pre-load classes and resourcesPreload (); Eventlog.writeevent (Log_boot_progress_preload_end, Systemclock.uptimemillis ());//End configuration Zygote initializationSamplingprofilerintegration.writezygotesnapshot ();//A garbage collectionGC ();//Disable tracingTrace.settracingenabled (false);//If requested, start System server directly from Zygote            if(Argv.length! =2) {Throw NewRuntimeException (argv[0] + usage_string); }if(argv[1].equals ("Start-system-server")) {startsystemserver ();//Start system_server process}Else if(!argv[1].equals ("")) {Throw NewRuntimeException (argv[0] + usage_string); } log.i (TAG,"Accepting command socket connections"); Runselectloop ();//handling customer connections and customer requestsCloseserversocket ();//Close the service side}Catch(Methodandargscaller caller)        {Caller.run (); }Catch(RuntimeException ex) {LOG.E (TAG,"Zygote died with exception", ex); Closeserversocket ();ThrowEx }    }

To summarize:
1. Call Registerzygotesocket to register the socket on the IPC communication server
2. Preload pre-load classes and resources
3. Startsystemserver Start System_server
4. Runselectloop processing customer connections and customer requests
Here the zygote process establishes a subprocess system_server, which is the core of the framework and maintains the same life cycle as zygote. However, the role of System_server will be reflected in the runselectloop.

Runselectloop Analysis

Before we know that Runselectloop is used to handle customer connections and customer requests, let's take a look at this approach.

    Private Static voidRunselectloop () throws Methodandargscaller {arraylist<filedescriptor> FDS =NewArraylist<filedescriptor> (); Arraylist<zygoteconnection> peers =NewArraylist<zygoteconnection> (); filedescriptor[] Fdarray =Newfiledescriptor[4];        Fds.add (Sserversocket.getfiledescriptor ()); Peers.add (NULL);intLoopcount = Gc_loop_count; while(true) {int Index;/ * * Call GC () before we block in select ().  * It's work, the has-to-be-done anyway, and it's better * to avoid making every child do It.             It would also * madvise () Any free memory as a side-effect.  * * Don ' t call it every time, because walking the entire * heap was a lot of overhead to free a few             Hundred bytes. */            if(Loopcount <=0) {GC ();            Loopcount = Gc_loop_count; }Else{loopcount--; }Try{Fdarray = Fds.toarray (Fdarray);//selectreadable is a native method that is used internally by select using the multiplexed I/O model                Index= Selectreadable (Fdarray); }Catch(IOException ex) {Throw NewRuntimeException ("Error in Select ()", ex); }if(Index<0) {Throw NewRuntimeException ("Error in Select ()"); }Else if(Index==0) {Zygoteconnection Newpeer = Acceptcommandpeer ();                Peers.add (Newpeer);            Fds.add (Newpeer.getfiledesciptor ()); }Else{BooleanDone Done = Peers.get (Index). RunOnce ();if(done) {Peers.remove (Index); Fds.remove (Index); }            }        }    }

In this procedure we can find that each time the customer is connected, the customer is represented by the Zygoteconnection object, and the client's request is handled by the Zygoteconnection RunOnce method.

At this point, our analysis of the zygote process and the end, it runs a long runselectloop method of deep sleep, the next important task will be processed in the system_server process execution.
Bibliography: In-depth understanding of Android Volume I

Android source code Analysis--zygote Process Analysis

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.