Android Roaming note (6)---app Launch Tour (I)

Source: Internet
Author: User
Tags strcmp

Android based on the linux2.6+ kernel, we look at a picture to have a perceptual understanding of the architecture of Android system.



We briefly explain from the kernel layer:

1, kernel layer: Based on the linux2.6+ core, at the same time do some embedded environment to do some targeted optimization adjustment.

2, libraries layer: including the Bionic C library, as well as the HAL (Hardware-driven interface abstraction) and other APIs.

3. Android Runtime (ART) layer: Includes core application library and Dalvik virtual machine.

4. Application Framework Layer: A pure Java API framework, including Activity Manager and Windows Manager.

5, Application layer: As the name implies, application layer, such as pre-installed phone, SMS, game app and so on.

Next, let's look at a typical Android app process image:

Enter PS on the command line to view the current list of processes:


Let's look at the process of the red circle callout, where 10002 is pid,137 as the parent process ID.


You can see that process number 137 is a mysterious "zygote" process, while the zygote parent process is the INIT process. The init process is the ancestor of all Android processes, while Zygote is the ancestor process for app apps.


At this point, we have a general understanding of the initial process of Android application launch, and below, we combine Aosp (Android Open Source Project) for a deeper analysis.

Android Open Source Library: Click to open link

First we start from App_main.cpp (click to open the link), this is the/system/bin/app_process C + + source, which is the parent process of all apps. We read directly against the source process, and I added a comment:

int main (int argc, char* const argv[]) {if (Prctl (Pr_set_no_new_privs, 1, 0, 0, 0) < 0) {//older kernels do N ' t understand Pr_set_no_new_privs and return//EINVAL.        Don ' t die on such kernels.            if (errno! = EINVAL) {log_always_fatal ("Pr_set_no_new_privs failed:%s", Strerror (errno));        return 12;    }} Appruntime Runtime (Argv[0], computeargblocksize (argc, argv));    Process command Line arguments//ignore argv[0] argc--;    argv++;    Everything up to '--' or first non '-' arg goes to the VM.    The first argument after the VM, args are the "parent dir", which//is currently unused.  After the parent dir, we expect one or more the following internal//arguments:////--zygote:start    In zygote mode//--start-system-server:start the system server.    --application:start in application (stand alone, non zygote) mode.    --nice-name:the nice name for this process. //    For non zygote starts, these arguments would be followed by//the main class name.    All remaining arguments is passed to//The main method of this class.    For zygote starts, all remaining arguments is passed to the zygote.    Main function.    int i = runtime.addvmarguments (argc, argv);  Parse runtime arguments.    Stop at first unrecognized option.    BOOL zygote = false;    BOOL Startsystemserver = false;    BOOL application = FALSE;    Const char* nicename = NULL;    String8 ClassName;  ++i;    Skip unused "parent dir" argument. while (I < ARGC) {const char* arg = argv[i++];/******************* start parameter contains--zygotenicename that is the process name, under ARM32, Zygote_nic            E_name = Zygote (ARM64 is zygote64) *******************/if (strcmp (ARG, "--zygote") = = 0) {zygote = true;        Nicename = Zygote_nice_name; The/******************* startup parameter contains--start-system-server Startsystemserver to True to start the system-server*******************/at the same time else if (strcmp(ARG, "--start-system-server") = = 0) {Startsystemserver = true; The/******************* startup parameter contains--application application to True, passing parameters to Dalvik*******************/else if (strcmp (ARG, "--        Application ") = = 0) {application = true;        } else if (strncmp (ARG, "--nice-name=", "n") = = 0) {nicename = arg + 12;            } else if (strncmp (ARG, "--", 2)! = 0) {Classname.setto (ARG);        Break            } else {-I.;        Break    }} vector<string8> args;  if (!classname.isempty ()) {//we ' re not in zygote mode, the only argument We need to pass//to Runtimeinit        is the application argument. The remainder of args get passed to startup class main (). make//copies of them before we overwrite them with the process name./******************* non-zygote mode processing ************** /Args.add (application?)        String8 ("Application"): String8 ("tool")); Runtime.setclassNameandargs (ClassName, argc-i, argv + i); } else {//We ' re in zygote mode./*******************zygote mode start processing *******************/maybecreatedalvikcache        ();        if (startsystemserver) {Args.add (String8 ("Start-system-server"));        } Char Prop[prop_value_max]; if (Property_get (Abi_list_property, prop, NULL) = = 0) {log_always_fatal ("app_process:unable to determine ABI            List from property%s. ", Abi_list_property);        return 11;        } String8 Abiflag ("--abi-list=");        Abiflag.append (prop);        Args.add (Abiflag);        In zygote mode, pass all remaining arguments to the zygote//Main () method.        for (; i < argc; ++i) {Args.add (String8 (Argv[i]));        }} if (Nicename && *nicename) {runtime.setargv0 (nicename);    Set_process_name (Nicename);     } if (zygote) {/*******************zygote Init,dalvik start *******************/   Runtime.start ("Com.android.internal.os.ZygoteInit", args);    } else if (className) {Runtime.start ("Com.android.internal.os.RuntimeInit", args);        } 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; }}

I have commented on a few key areas of the code above, and we look at the init.rc in the Android root directory, which can be found in the following line:


Its role is to initialize the zygote process.

Zygote boot process can be described as follows: Execute app_process, and modify the process name zygote, and according to the incoming Start-system-server parameters, start the System-server service, while initializing Dalvik virtual machine. Let's look at the source of this class Androidruntime (click Open link), where the start function has two functions, one is to start the Dalvik VM, The first is to execute the main function of the com.android.internal.os.ZygoteInit, and pass the relevant parameters to realize the zygote initialization work.


Let's look at the source code for this Java class (click the Open link) and see what Com.android.internal.os.ZygoteInit is doing.

</pre></p><p style= "Text-align:left;" ><pre name= "code" class= "java" >public static void Main (String argv[]) {try {//Start Profilin            G The zygote initialization.            Samplingprofilerintegration.start ();            Boolean startsystemserver = false;            String socketname = "zygote";            String abilist = null; for (int i = 1; i < argv.length; i++) {if ("Start-system-server". Equals (Argv[i])) {/* Prepare to start system_server*                /Startsystemserver = true;                } else if (Argv[i].startswith (Abi_list_arg)) {abilist = Argv[i].substring (Abi_list_arg.length ());                    } else if (Argv[i].startswith (Socket_name_arg)) {/*zygote listener socketname, default =/dev/socket/zygote */                Socketname = argv[i].substring (Socket_name_arg.length ());         } else {throw new runtimeexception ("Unknown command line argument:" + argv[i]);       }} if (abilist = = null) {throw new RuntimeException ("No ABI list supplied.")            );            }/** registered socket*/registerzygotesocket (socketname);            Eventlog.writeevent (Log_boot_progress_preload_start, Systemclock.uptimemillis ());            Preload ();            Eventlog.writeevent (Log_boot_progress_preload_end, Systemclock.uptimemillis ());            Finish profiling the zygote initialization.            Samplingprofilerintegration.writezygotesnapshot ();            Do a initial GC to clean up after startup GC ();            Disable tracing So, forked processes do not inherit stale tracing tags from//Zygote.            Trace.settracingenabled (FALSE);            if (startsystemserver) {startsystemserver (abilist, socketname);            } log.i (TAG, "accepting command socket connections");            Runselectloop (abilist); CloSeserversocket ();        } catch (Methodandargscaller caller) {Caller.run ();            } catch (RuntimeException ex) {LOG.E (TAG, "Zygote died with exception", ex);            Closeserversocket ();        Throw ex; }    }

Zygoteinit completed the actual system_server boot, while initializing the zygote socket listener (/dev/socket/zygote this pseudo-device file), so that finally completed the app launch all the preparation, note that this is just the preparation work, The actual startup process is as follows:


1, Launcher (Android "launch process", you can see the desktop, application list, etc. are Launcher content) process to hear the application launch event, such as you clicked the app icon;

2. Through Binder (Android cross-process Communication framework IPC), the Activity Manager service is notified across processes to initiate activity. Activitymanager call Zygote.forkandspecialize to fork a new app subprocess and return the PID, then call the app's start activity OnStart and OnCreate method to complete the launch!

Let's look at the fork function (click to open the link): The role of Fork is "clone" a new sub-process that is consistent with the current process structure (not a complete copy of course)! This is a smart way to do Android, according to the Linux cow (Copy on Write) theory, the newly generated process will "share" the parent process of all the library link information, and will load their own specific lib, such as Bionic libc Library is shared by all apps, Since it is read-only, all apps share a "physical storage" libc library instead of one copy per app.

Let's look at the memory maps fragment of the zygote process:


/system/lib These C libraries are shared by all app processes, although they may be in different virtual addresses in different app processes, but "share" a physical store! The memory image of the other app starts from this zygote full "copy"!


reprint Please indicate source: Life show Enjoy it!

Related Article

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.