Android in Layman's zygote

Source: Internet
Author: User

One purpose

Zygote, is a thing that Android got out of. There's a lot of talk on the Internet. The first time I saw this name, I was depressed, what do you want? Linux under the name have been very easy to understand, popular. Zygote Don't you want to imitate the fork under Linux? Personally, Google takes a strange name, including Google itself.

Anyway, zygote is still at the heart of the Android system, zygote is a fertilized egg, and can be considered an ancestor of the Android Framework's big family! Our purpose in this section is to describe the context of the next zygote, by the way, exposing its shortcomings, we can remedy the case, the mutation of a more fine variety.

Two Zygote

Zygote itself is an application layer of the program, and the driver, kernel modules and other things do not matter. Do you feel relieved? The startup of Zygote is initiated by the ancestor Init of Linux. This is mentioned in the INIT analysis. I won't say it here.

The process seen in Zygote,ps is called Zygote, whose initial name is App_process, which is changed to "Zygote" by calling Pctrl directly. But it doesn't affect our analysis.

The zygote code is in Framework/base/cmds/app_process/app_main.cpp. We take a step-by-step look.

Since it is an application, look directly at main.

[---->main]

int main (int argc, const char* Const argv[])

{

Parameter is important Ah, remember the init analysis?

Well, these are the parameters: (be sure to remember our situational analysis Method!) )

Zygote/system/bin/app_process

-xzygote/system/bin--zygote--start-system-server

These is global variables in ProcessState.cpp

MARGC = ARGC;

MARGV = argv;

Marglen = 0;

for (int i=0; i<argc; i++) {

Marglen + = strlen (Argv[i]) + 1;

}

marglen--;

Appruntime runtime;

What the hell is a appruntime? Addvmarguments, it seems to have something to do with a virtual machine.

int i = runtime.addvmarguments (argc, argv);

[--->appruntime]

Class Appruntime:public Androidruntime

Deriving from Androidruntime is a convenient class for interacting with Dalvik, which is not the first to say.

[---->main]

...

int i = runtime.addvmarguments (argc, argv);

....

if (I < ARGC) {

arg = argv[i++];

if (0 = = strcmp ("--zygote", Arg)) {

BOOL Startsystemserver = (i < ARGC)?

strcmp (Argv[i], "--start-system-server") = = 0:false;

Nonsense, according to our parameters, Startsystemserver=true

SetArgv0 (Argv0, "zygote");

Rename word, do not know how to change under Windows, Linux can be used Pctrl system calls

Set_process_name ("zygote");

Start Remember our parameters.

Runtime.start ("Com.android.internal.os.ZygoteInit",

Startsystemserver);

}

} else {

return 10;

}

Ft,app_main is still very simple, but runtime.start look not simple ah, passed in the parameter

"Com.android.internal.os.ZygoteInit" is quite like the naming convention for Java classes.

2.1 Appruntime

Well, the code goes into Runtime.start ("Com.android.internal.os.ZygoteInit", true). SOURCE insight go straight in and see. The code is in Framework/base/core/jni/appruntime.cpp.

[--->void androidruntime::start ()]

void Androidruntime::start (const char* className, const BOOL startsystemserver)

{

LOGD ("\n>>>>>>>>>>>>>> androidruntime START <<<<<< <<<<<<<<\n ");

char* slashclassname = NULL;

char* CP;

jnienv* env;

Linux under Signal processing, nothing to say

Blocksigpipe ();

Set environment variable Android_root to/system

Const char* RootDir = getenv ("Android_root");

if (RootDir = = NULL) {

RootDir = "/system";

Setenv ("Android_root", RootDir, 1);

}

/* Start the virtual machine */

if (STARTVM (&MJAVAVM, &env)! = 0)

Goto bail;

Starting a virtual machine, is it related to Java? The most important SDK for Android is Java, and that part of the virtual machine is definitely going to look inside.

[--->int ANDROIDRUNTIME::STARTVM ()]

int ANDROIDRUNTIME::STARTVM (javavm** pjavavm, jnienv** penv)

{

Alas, most of the startup parameters are set for the Java Virtual machine. However, there are several parameters that are more important.

Checkjni, may not have used JNI for a lifetime can not understand

To be blunt, it is when we call the JNI function in the C + + layer that we check the parameters or whatever.

If it's not legal, just exit! the virtual machine. The first one affects the speed and the second is the impact program.

This is used only as a development time.

Property_get ("Dalvik.vm.checkjni", Propbuf, "");

if (strcmp (Propbuf, "true") = = 0) {

Checkjni = true;

} else if (strcmp (Propbuf, "false")! = 0) {

/* property is neither true nor false; Fall back on kernel parameter */

Property_get ("Ro.kernel.android.checkjni", Propbuf, "");

if (propbuf[0] = = ' 1 ') {

Checkjni = true;

}

}

Set virtual machine Max HeapSize, just give 16M, seems a little bit less, especially in doing picture operation

A random hundreds of trillion picture will kill the virtual machine.

strcpy (Heapsizeoptsbuf, "-xmx");

Property_get ("Dalvik.vm.heapsize", Heapsizeoptsbuf+4, "16m");

opt.optionstring = Heapsizeoptsbuf;

Moptions.add (opt);

LOGD ("Checkjni is%s\n", Checkjni? "On": "OFF");

if (CHECKJNI) {

/* Extended JNI Checking */

opt.optionstring = "-xcheck:jni";

Moptions.add (opt);

/* Set a cap on JNI global references */

opt.optionstring = "-xjnigreflimit:2000";

Moptions.add (opt);

}

Specific Dalvik what are the parameters of the virtual machine, you can refer to the Dalvik instructions

Anyway, the following function is called, and the virtual machine is started by the parameters you specified.

if (JNI_CREATEJAVAVM (PJAVAVM, penv, &initargs) < 0) {

LOGE ("JNI_CREATEJAVAVM failed\n");

Goto bail;

}

result = 0;

Bail:

Free (stacktracefile);

return result;

}

OK, virtual machine up and see what else we're going to do in Runtime.start.

[--->void androidruntime::start ()]

if (STARTVM (&MJAVAVM, &env)! = 0)

...

Startreg?

if (Startreg (env) < 0) {

Goto bail;

}

Take a look.

[--->int androidruntime::startreg ()]

Why not change Startreg to Startregister ().

int Androidruntime::startreg (jnienv* env)

{

The name is still very clear, set the function of creating thread to be javacreatethreadetc

Androidsetcreatethreadfunc ((ANDROID_CREATE_THREAD_FN) javacreatethreadetc);

JNI knowledge, check the JDK yourself.

Env->pushlocalframe (200);

//

if (Register_jni_procs (Gregjni, Nelem (GREGJNI), env) < 0) {

Env->poplocalframe (NULL);

return-1;

}

Env->poplocalframe (NULL);

Funny, why don't you kill the note below?

Createjavathread ("Fubar", QuickTest, (void*) "Hello");

return 0;

}

[---->static int register_jni_procs ()]

static int Register_jni_procs (const REGJNIREC array[], size_t count, jnienv* env)

{

for (size_t i = 0; i < count; i++) {

if (Array[i].mproc (env) < 0) {//Do nothing, controlled by the parameters passed in. Waste my time.

return-1;

}

}

return 0;

}

Back to the previous call,

Register_jni_procs (Gregjni, Nelem (GREGJNI), env), its parameter gregjni is the following structure

static const REGJNIREC gregjni[] = {

Reg_jni (Register_android_debug_jnitest),

Reg_jni (Register_com_android_internal_os_runtimeinit),

Reg_jni (Register_android_os_systemclock),

Reg_jni (Register_android_util_eventlog),

Reg_jni (Register_android_util_log),

... There's a lot more behind, like some kind of function.

};

Pick one and take a look inside.

[--->int register_android_debug_jnitest]

int Register_android_debug_jnitest (jnienv* env)

{

Return Jniregisternativemethods (env, "Android/debug/jnitest",

Gmethods, Nelem (gmethods));

}

is actually registering some Java native functions in the C + + layer corresponding to the implementation function.

So:

If you can add your custom-made things to this place.

Well, Startreg is finished, back to Runtime.start.

[---->void Androidruntime::start]

if (Startreg (env) < 0) {

Goto bail;

}

Jclass Stringclass;

Jobjectarray Strarray;

Jstring Classnamestr;

Jstring Startsystemserverstr;

These are the strings that turn C + + strings into Java.

//

Stringclass = Env->findclass ("java/lang/string");

Constructs a string array with an element number of 2

Strarray = Env->newobjectarray (2, Stringclass, NULL);

Classnamestr = Env->newstringutf (className);

Env->setobjectarrayelement (strarray, 0, CLASSNAMESTR);

Startsystemserverstr = Env->newstringutf (startsystemserver?) "True": "false");

Env->setobjectarrayelement (Strarray, 1, STARTSYSTEMSERVERSTR);

Does the Java application also have a main function? The above is the C + + passed in parameters, into the Java parameters

[

"Com.android.internal.os.ZygoteInit",

"True"

]

Jclass Startclass;

Jmethodid Startmeth;

//

Startclass = Env->findclass (slashclassname);

The next JNI call, it really goes into the Java layer.

Startmeth = Env->getstaticmethodid (Startclass, "main", "([ljava/lang/string;) V");

The following call is the main function of the Com.android.internal.os.ZygoteInit class

The last argument is true

Env->callstaticvoidmethod (Startclass, Startmeth, Strarray);

Bail:

Free (slashclassname);

}

Thank you for your support for in-depth understanding of Android Volume I/Vol. ii.

Android in Layman's zygote

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.