1. app_process到zygote

zygote本身是一个Native应用程序,和驱动、内核均无关系,zygote是由init进行根据init.rc文件中的配置进行创建的,具体的配置代码如下:

1.1 zygote启动的init.rc文件定义

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-serverclass mainsocket zygote stream 660 root systemonrestart write /sys/android_power/request_state wakeonrestart write /sys/power/state ononrestart restart mediaonrestart restart netd

  上面的代码中可以看出,zygote的原名是app_precess,在启动的时候是通过Linux下的pctrl系统调用将自己改名为zygote,app_process对应的源文件是App_main.cpp.

1.2 App_main.cpp的main函数

int main(int argc, char* const argv[])
{// argc = 5, argv = “/system/bin/app_process -Xzygote /system/bin --zygote --start-system-server”………….AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));argc--;    // 跳过第一个参数/system/bin/app_precessargv++;// -Xzygote为虚拟机参数,在启动虚拟机是传递到虚拟机int i;for (i = 0; i < argc; i++) {if (argv[i][0] != '-') {break;}if (argv[i][1] == '-' && argv[i][2] == 0) {++i; // Skip --.break;}runtime.addOption(strdup(argv[i]));}// Parse runtime arguments.  Stop at first unrecognized option.bool zygote = false;bool startSystemServer = false;bool application = false;String8 niceName;String8 className;// 跳过 /system/bin参数++i;  // Skip unused "parent dir" argument.// 根据参数进行赋值while (i < argc) {const char* arg = argv[i++];if (strcmp(arg, "--zygote") == 0) {zygote = true;niceName = ZYGOTE_NICE_NAME;} else if (strcmp(arg, "--start-system-server") == 0) {startSystemServer = true;} else if (strcmp(arg, "--application") == 0) {application = true;} else if (strncmp(arg, "--nice-name=", 12) == 0) {niceName.setTo(arg + 12);} else if (strncmp(arg, "--", 2) != 0) {className.setTo(arg);break;} else {--i;break;}}Vector<String8> args;if (!className.isEmpty()) {  // className未赋值,跳过args.add(application ? String8("application") : String8("tool"));runtime.setClassNameAndArgs(className, argc - i, argv + i);} else {// We're in zygote mode.// 设置指令集、划分虚拟机使用的cache、将cache文件的权限设置为711,同时修改拥有者为root usermaybeCreateDalvikCache();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;}// 添加ABI_LISTString8 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]));}}// 修改线程名为zygoteif (!niceName.isEmpty()) {runtime.setArgv0(niceName.string());set_process_name(niceName.string());}// 根据得到的参数调用com.android.internal.os.ZygoteInit// args这个vector中包含两个成员,args[0] = “start-system-server”// args[1] = “—abi-list=xxx” xxx代码的是CPU的结构,比如armeabi-v7a, arm64-v8aif (zygote) {runtime.start("com.android.internal.os.ZygoteInit", args, zygote);} else if (className) {runtime.start("com.android.internal.os.RuntimeInit", args, zygote);} 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;}
}

2. AppRuntime分析

AppRuntime类的声明和实现都在App_main.cpp中,它是从AndroidRuntime类派生出来的,代码如下:

2.1 AndroidRuntime.cpp的start函数

// className = "com.android.internal.os.ZygoteInit", options包含两个string8成员
// args[0] = “start-system-server” args[1] = “—abi-list=xxx”, zygote = true
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{ALOGD(">>>>>> START %s uid %d <<<<<<\n",className != NULL ? className : "(unknown)", getuid());static const String8 startSystemServer("start-system-server");/** 'startSystemServer == true' means runtime is obsolete and not run from* init.rc anymore, so we print out the boot start event here.*/for (size_t i = 0; i < options.size(); ++i) {if (options[i] == startSystemServer) {/* 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)));}}const 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);}//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, zygote) != 0) {return;}onVmCreated(env);/** Register android functions.*/// 设置虚拟机的JNI环境if (startReg(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.*/// 调用JNI方法调用com.android.internal.os.ZygoteInit中的main方法jclass stringClass;jobjectArray strArray;jstring classNameStr;stringClass = env->FindClass("java/lang/String");assert(stringClass != NULL);strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);assert(strArray != NULL);classNameStr = env->NewStringUTF(className);assert(classNameStr != NULL);env->SetObjectArrayElement(strArray, 0, classNameStr);for (size_t i = 0; i < options.size(); ++i) {jstring optionsStr = env->NewStringUTF(options.itemAt(i).string());assert(optionsStr != NULL);env->SetObjectArrayElement(strArray, i + 1, optionsStr);}// 至此,strArray中包含三个成员,分别是 // strArray[0] = “com.android.internal.os.ZygoteInit”// strArray[1] = “start-system-server”// strArray[2] = “—abi-list=xxx”/** Start VM.  This thread becomes the main thread of the VM, and will* not return until the VM exits.*/// className=”com.android.internal.os.ZygoteInit”,调用如下方法后,// slashClassName=”com/android/internal/os/ZygoteInit”char* slashClassName = toSlashClassName(className);jclass startClass = env->FindClass(slashClassName);if (startClass == NULL) {ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);/* keep going */} else {// 找到ZygoteInit的main方法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 {// 调用ZygoteInit的main方法env->CallStaticVoidMethod(startClass, startMeth, strArray);#if 0if (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");
}

  上述内容都是在Native层运行的,但是在调用ZygoteInit的main方法后,程序便会进入到Java的世界里面,下面来看看上面没有具体解释道的startVm和startReg方法。

2.2 AndroidRuntime.cpp的startVm函数

int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote)
{JavaVMInitArgs initArgs;……….// 这里很多char buffer的定义,都去掉了/*下面很多代码都是用来设置JNI Check选项的。JNI Check顾名思义是指Native层调用JNI函数时,系统所做的检查工作。例如,调用NewUTFString函数的时候,系统会检查传入的字符串是不是符合UTF-8的要求,JNI Check汉能检查资源是否被正确释放。但是开启这个选项也是有副作用的,主要表现为:1)因为检查工作比较耗时,所以会影响系统的运行速度2)有些检查过于严格,例如上面的字符串检查,一旦报错,调用进程就会abort所以JNI Check一般是在eng版本会设置,在正式发布的user版本就不设置该选项*/bool checkJni = false;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;}}ALOGD("CheckJNI is %s\n", checkJni ? "ON" : "OFF");if (checkJni) {/* extended JNI checking */addOption("-Xcheck:jni");/* with -Xcheck:jni, this provides a JNI function call trace *///addOption("-verbose:jni");}property_get("dalvik.vm.execution-mode", propBuf, "");if (strcmp(propBuf, "int:portable") == 0) {executionMode = kEMIntPortable;} else if (strcmp(propBuf, "int:fast") == 0) {executionMode = kEMIntFast;} else if (strcmp(propBuf, "int:jit") == 0) {executionMode = kEMJitCompiler;}// 设置虚拟机产生的trace文件,主要用于分析系统问题,默认路劲可以通过adb shell连接手机执行getprop | grep trace查看parseRuntimeOption("dalvik.vm.stack-trace-file", stackTraceFileBuf, "-Xstacktracefile:");strcpy(jniOptsBuf, "-Xjniopts:");if (parseRuntimeOption("dalvik.vm.jniopts", jniOptsBuf, "-Xjniopts:")) {ALOGI("JNI options: '%s'\n", jniOptsBuf);}………../** The default starting and maximum size of the heap.  Larger* values should be specified in a product property override.*/parseRuntimeOption("dalvik.vm.heapstartsize", heapstartsizeOptsBuf, "-Xms", "4m");parseRuntimeOption("dalvik.vm.heapsize", heapsizeOptsBuf, "-Xmx", "16m");parseRuntimeOption("dalvik.vm.heapgrowthlimit", heapgrowthlimitOptsBuf, "-XX:HeapGrowthLimit=");parseRuntimeOption("dalvik.vm.heapminfree", heapminfreeOptsBuf, "-XX:HeapMinFree=");parseRuntimeOption("dalvik.vm.heapmaxfree", heapmaxfreeOptsBuf, "-XX:HeapMaxFree=");parseRuntimeOption("dalvik.vm.heaptargetutilization",heaptargetutilizationOptsBuf,"-XX:HeapTargetUtilization=");// 接下来很多都是设置虚拟机参数,具体可以自行查看………./** When running with debug.generate-debug-info, add --generate-debug-info to* the compiler options so that the boot image, if it is compiled on device,* will include native debugging information.*/property_get("debug.generate-debug-info", propBuf, "");if (strcmp(propBuf, "true") == 0) {addOption("-Xcompiler-option");addOption("--generate-debug-info");addOption("-Ximage-compiler-option");addOption("--generate-debug-info");}/** Retrieve the build fingerprint and provide it to the runtime. That way, ANR dumps will* contain the fingerprint and can be parsed.*/parseRuntimeOption("ro.build.fingerprint", fingerprintBuf, "-Xfingerprint:");initArgs.version = JNI_VERSION_1_4;initArgs.options = mOptions.editArray();initArgs.nOptions = mOptions.size();initArgs.ignoreUnrecognized = JNI_FALSE;/** Initialize the VM.** The JavaVM* is essentially per-process, and the JNIEnv* is per-thread.* If this call succeeds, the VM is ready, and we can start issuing* JNI calls.*/// 初始化虚拟机if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {ALOGE("JNI_CreateJavaVM failed\n");return -1;}return 0;
}

接下来看startReg函数:

2.3 AndroidRuntime.cpp的startReg函数

/** Register android native functions with the VM.*/
/*static*/ int AndroidRuntime::startReg(JNIEnv* env)
{/** This hook causes all future threads created in this process to be* attached to the JavaVM.  (This needs to go away in favor of JNI* Attach calls.)*/// 设置Thread类的线程创建函数为javaCreateThreadEtc,androidSetCreateThreadFunc下面分析androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);ALOGV("--- registering native functions ---\n");/** Every "register" function calls one or more things that return* a local reference (e.g. FindClass).  Because we haven't really* started the VM yet, they're all getting stored in the base frame* and never released.  Use Push/Pop to manage the storage.*/env->PushLocalFrame(200);// 注册JNI函数,gRegJNI是个全局数组,register_jni_procs下面分析if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {env->PopLocalFrame(NULL);return -1;}env->PopLocalFrame(NULL);//createJavaThread("fubar", quickTest, (void*) "hello");return 0;
}

  androidSetCreateThreadFunc代码如下,非常简单,只是将gCreateThreadFn指向javaCreateThreadEtc

void androidSetCreateThreadFunc(android_create_thread_fn func)
{gCreateThreadFn = func;
}

  register_jni_procs则是简单的封装,调用数组元素的MProc函数

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) {
#ifndef NDEBUGALOGD("----------!!! %s failed to load\n", array[i].mName);
#endifreturn -1;}}return 0;
}

其中gRegJNI定义如下,包含的是要注册到JNI中的函数

static const RegJNIRec gRegJNI[] = {REG_JNI(register_com_android_internal_os_RuntimeInit),REG_JNI(register_android_os_SystemClock),REG_JNI(register_android_util_EventLog),………..
}

REG_JNI是一个宏,定义如下:

#ifdef NDEBUG#define REG_JNI(name)      { name }struct RegJNIRec {int (*mProc)(JNIEnv*);};
#else#define REG_JNI(name)      { name, #name }struct RegJNIRec {int (*mProc)(JNIEnv*);const char* mName;};
#endif

当调用array[i].mProc(env)就相当于调用相应的函数

3. Java World

上面分析到,在AndroidRuntime.cpp的start函数的最后调用CallStaticVoidMethod方法,该方法会调用到com.android.internal.os.ZygoteInit的main函数。

3.1 ZygoteInit.java的main函数

public static void main(String argv[]) {try {RuntimeInit.enableDdms();   // 开启DDMS功能/// M: Added for BOOTPROF//MTPROF_DISABLE = "1".equals(SystemProperties.get("ro.mtprof.disable"));MTPROF_DISABLE = false;// Start profiling the zygote initialization.SamplingProfilerIntegration.start();boolean startSystemServer = false;String socketName = "zygote";String abiList = null;// 解析传入的argv参数,其中argv就是AndroidRuntime.cpp中的strArray// strArray[0] = “com.android.internal.os.ZygoteInit”// strArray[1] = “start-system-server”// strArray[2] = “—abi-list=xxx”for (int i = 1; i < argv.length; i++) {if ("start-system-server".equals(argv[i])) {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)) {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.");}// 注册Zygote使用的socketregisterZygoteSocket(socketName);EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,SystemClock.uptimeMillis());/// M: Added for BOOTPROFaddBootEvent(new String("Zygote:Preload Start"));// 预加载类和相应资源preload();EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,SystemClock.uptimeMillis());// Finish profiling the zygote initialization.SamplingProfilerIntegration.writeZygoteSnapshot();// Do an initial gc to clean up after startup// 强制执行gc进行一次垃圾回收gcAndFinalize();// Disable tracing so that forked processes do not inherit stale tracing tags from// Zygote.Trace.setTracingEnabled(false);/// M: Added for BOOTPROFaddBootEvent(new String("Zygote:Preload End"));// startSystemServer为trueif (startSystemServer) {// 启动system_server进程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;}
}

3.2 ZygoteInit.java的registerZygoteSocket函数

// socketName=”zygote”
private static void registerZygoteSocket(String socketName) {if (sServerSocket == null) {int fileDesc;// fullSocketName=”ANDROID_SOCKEY_zygote”final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;try {// 这个应该是在之前有设置相应的环境变量,这里取出来String env = System.getenv(fullSocketName);fileDesc = Integer.parseInt(env);} catch (RuntimeException ex) {throw new RuntimeException(fullSocketName + " unset or invalid", ex);}try {FileDescriptor fd = new FileDescriptor();fd.setInt$(fileDesc);    // 设置文件描述符sServerSocket = new LocalServerSocket(fd);    // 创建socket本地服务端} catch (IOException ex) {throw new RuntimeException("Error binding to local socket '" + fileDesc + "'", ex);}}
}

3.3 ZygoteInit.java的preload函数

static void preload() {Log.d(TAG, "begin preload");Log.i(TAG1, "preloadMappingTable() -- start ");PluginLoader.preloadPluginInfo();Log.i(TAG1, "preloadMappingTable() -- end ");// 预加载位于system/etc/preload-class文件中指定的class// preloadClasses()最后会通过Class.forName(String, Boolean, ClassLoader)来加载preloade-class中指定的class文件// system/etc/preload_class文件在源码的位置为framework/base/preload-classpreloadClasses();// 预加载资源,包括drawable和color资源preloadResources();// 预加载OpenGLpreloadOpenGL();// 通过System.LoadLibrary()方法// 预加载”android”, ”compiler-rt” 和 “jnigraphics”三个共享库preloadSharedLibraries();// 预加载文本资源preloadTextResources();// Ask the WebViewFactory to do any initialization that must run in the zygote process,// for memory sharing purposes.WebViewFactory.prepareWebViewInZygote();Log.d(TAG, "end preload");
}

3.4 ZygoteInit.java的startSystemServer

private static boolean startSystemServer(String abiList, String socketName)throws MethodAndArgsCaller, RuntimeException {long capabilities = posixCapabilitiesAsBits(OsConstants.CAP_BLOCK_SUSPEND,OsConstants.CAP_KILL,OsConstants.CAP_NET_ADMIN,OsConstants.CAP_NET_BIND_SERVICE,OsConstants.CAP_NET_BROADCAST,OsConstants.CAP_NET_RAW,OsConstants.CAP_SYS_MODULE,OsConstants.CAP_SYS_NICE,OsConstants.CAP_SYS_RESOURCE,OsConstants.CAP_SYS_TIME,OsConstants.CAP_SYS_TTY_CONFIG);/* Hardcoded command line to start the system server */// 启动参数设置String args[] = {"--setuid=1000","--setgid=1000","--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1032,3001,3002,3003,3006,3007","--capabilities=" + capabilities + "," + capabilities,"--nice-name=system_server","--runtime-args","com.android.server.SystemServer",};ZygoteConnection.Arguments parsedArgs = null;int pid;try {// 解析参数,将上面的字符串数据转换成Arguments对象parsedArgs = new ZygoteConnection.Arguments(args);ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);/* Request to fork the system server process */// fork一个子进程,子进程就是system_server进程pid = Zygote.forkSystemServer(parsedArgs.uid, parsedArgs.gid,parsedArgs.gids,parsedArgs.debugFlags,null,parsedArgs.permittedCapabilities,parsedArgs.effectiveCapabilities);} catch (IllegalArgumentException ex) {throw new RuntimeException(ex);}/* For child process */// ford返回值等于0,表明是子进程即system_server所在分支代码if (pid == 0) {if (hasSecondZygote(abiList)) {waitForSecondaryZygote(socketName);}// system_server进程所做的工作,在这里会启动各种支撑系统运行的System serverhandleSystemServerProcess(parsedArgs);}return true;
}

Zygeto进行fork后,分裂出一个system_server进程,这里主要介绍Zygote,system_server内容后面再介绍

3.5 ZygoteInit.java的runSelectLoop函数

private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();// sServerSocket是在1.3.2创建的Zygote本地服务端socket,现在将其添加到fds[0]中fds.add(sServerSocket.getFileDescriptor());peers.add(null);while (true) {StructPollfd[] pollFds = new StructPollfd[fds.size()];for (int i = 0; i < pollFds.length; ++i) {pollFds[i] = new StructPollfd();pollFds[i].fd = fds.get(i);pollFds[i].events = (short) POLLIN;}try {// 通过select机制来处理轮询,提高性能,当有pooFds到来,进程会从这里唤醒,否则一直阻塞Os.poll(pollFds, -1);} catch (ErrnoException ex) {throw new RuntimeException("poll failed", ex);}for (int i = pollFds.length - 1; i >= 0; --i) {// 使用多路复用I/O模型,当有连接或者接收到对端的数据才继续往下执行// 否则,使用continue,跳出循环后继续等待连接or接受数据if ((pollFds[i].revents & POLLIN) == 0) {continue;}if (i == 0) {// 表示有新连接到来ZygoteConnection newPeer = acceptCommandPeer(abiList);peers.add(newPeer);fds.add(newPeer.getFileDesciptor());} else {// 表示接收到对端发出的数据,调用runOnce()进行数据处理boolean done = peers.get(i).runOnce();if (done) {peers.remove(i);fds.remove(i);}}}}
}

runSelectLoop的主体是一个死循环,它将用作zygote的守护体存在

3.6 ZygoteInit.java的runOnce函数

代码如下,省略了大部分内容

boolean runOnce() throws MethodAndArgsCaller {ZygoteConnection.Arguments parsedArgs = null;…………..try {……….// zygote需为新启动的应用程序生成独立的进程实体,这个工作就委托到forkAndSpecialize函数来做pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, ex, parsedArgs.mountExternal, parsedArgs.seInfo, parsedArgs.niceName);} catch (IOException var17) {…………..boolean ex1;try {// 父进程需要完成的内容if(pid != 0) {IoUtils.closeQuietly(childPipeFd);childPipeFd = null;ex1 = this.handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);return ex1;}// 子进程需要完成的内容IoUtils.closeQuietly(serverPipeFd);serverPipeFd = null;this.handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);ex1 = true;} finally {IoUtils.closeQuietly(childPipeFd);IoUtils.closeQuietly(serverPipeFd);}return ex1;}
}

3.7 Zygote.java的forkAndSpecialize函数

public static int forkAndSpecialize(int uid, int gid, int[] gids, int debugFlags,int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,String instructionSet, String appDataDir) {VM_HOOKS.preFork();int pid = nativeForkAndSpecialize(uid, gid, gids, debugFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,instructionSet, appDataDir);// Enable tracing as soon as possible for the child process.if (pid == 0) {Trace.setTracingEnabled(true);// Note that this event ends at the end of handleChildProc,Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");}VM_HOOKS.postForkCommon();return pid;
}

  forkAndSpecialize函数实在“孵化”的同时将新创建的进程转换为目标Android应用程序。函数forkAndSpecialize包含三个步骤,分别是preFork、nativeForkAndSpecialize和postForkCommon。preFork通过JNI调用到dalvik_system_ZygoteHooks.cc中的ZygoteHooks_nativePreFork函数,在这个函数中会通过runtime->PreZygoteFork来进行前期初始化。

  函数nativeForkAndSpecialize也是一个native方法,实现在com_android_internal_os_
Zygote_nativeForkAndSpecialize中,而之后又会进一步调用到FordAndSpecializeCommon方法。在FordAndSpecializeCommon方法中会通过Linux fork调用孵化出一个新的进程,然后调用到CallStaticVoidMethod这个JNI方法来执行一些孵化后的处理,但是这里并没有进行应用程序相关的业务,真正的业务执行是在runOnce中提到的handleChildProc中,之后的内容这里就不做解释了,后续在AMS中应该会提及。

http://blog4jimmy.com/2018/01/326.html

Android Zygote分析相关推荐

  1. CSDN移动博文集锦之Android核心分析 (Z)

    导读:对于Android开发者来说,成系列的技术文章对他们的技术成长帮助最大.如下是我们向您强烈推荐的主题为Android开发的第一个系列文章. 文章皆来自CSDN网友maxleng的专栏,maxle ...

  2. 冷冰:Android核心分析系列

    1. 方法论探讨之设计意图 2. 方法论探讨之概念空间篇 3. 手机之硬件形态 4. 手机的软件形态 5. Android基本空间划分 6. IPC框架分析(Binder,Service,Servic ...

  3. Android手机开发总结——Android核心分析

    导读:对于Android开发者来说,成系列的技术文章对他们的技术成长帮助最大.如下是我们向您强烈推荐的主题为Android开发的第一个系列文章. <Android核心分析>整理如下: 1. ...

  4. Android核心分析

    导读:对于Android开发者来说,成系列的技术文章对他们的技术成长帮助最大.如下是我们向您强烈推荐的主题为Android开发的第一个系列文章. <Android核心分析>整理如下: 1. ...

  5. Android 核心分析 之七------Service深入分析

    http://blog.csdn.net/maxleng/article/details/5504485 Service深入分析 上一章我们分析了Android IPC架构,知道了Android服务构 ...

  6. android hprof,Android Hprof 分析

    Android Studio 中的 HProf静态分析 HProf 在 Android Studio 中的展示详解,基于我对其的理解,我将其根据 heap,count,size,其他将其分成了 4 个 ...

  7. android逆向分析概述_Android存储概述

    android逆向分析概述 Storage is this thing we are all aware of, but always take for granted. Not long ago, ...

  8. Android JNI入门第五篇——Android.mk分析

    转载请标明出处: http://blog.csdn.net/michael1112/article/details/56671708 江东橘子的博客 Android.mk文件是在使用NDK编译C代码时 ...

  9. Android多线程分析之二:Thread的实现

    Android多线程分析之二:Thread的实现 罗朝辉 (http://www.cnblogs.com/kesalin/) CC 许可,转载请注明出处 在前文<Android多线程分析之一:使 ...

最新文章

  1. 25个iptables常用示例
  2. 英特尔九州云99Cloud OpenStack行业应用研讨会
  3. 分享Silverlight/WPF/Windows Phone一周学习导读(3月14日-3月19日)
  4. 【精品资源】干货分享:20款精美的手机网站模板下载
  5. 互联网晚报 | 04月07日 星期四 |​ ​​​​刘强东卸任京东集团CEO,徐雷接任;世卫组织:中医药对治疗新冠有效...
  6. Linux 文件系统之 inode 概述
  7. c语言最新标准 2017,2017最新C语言介绍
  8. 搭建测试环境、面向对象
  9. 46.贪心算法练习:  区间合并
  10. 准备系统地学习一下Python
  11. windows搜索神器Everything
  12. 前端 HTML5+CSS3基础知识一
  13. 西门子博图安装期间反复重启的问题处理
  14. FBReader 探究
  15. Ubuntu 命令行 安装 Operator Mono 字体
  16. CPU硅脂需要换吗?
  17. earn the python in hard way习题31~35的附加习题
  18. 37.图灵接口及电脑语音聊天
  19. 慢扫描电视 SSTV
  20. Excel调整行高,鼠标右键直接选中一行进行调整了

热门文章

  1. Android启动Activity的两种方式与四种启动模式
  2. 关于引用传递的测试题
  3. 关于深度学习的一点理解
  4. stm32固件库assert_param()
  5. Linux下文件描述符
  6. 6、VTK基本数据结构
  7. ubuntu如何编辑/etc/ld.so.conf
  8. 科大星云诗社动态20210821
  9. [MATLAB粒子模拟笔记]归一化输入系数
  10. 6 种激活函数核心知识点,请务必掌握!