Android Zygote分析
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分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android智能指针
- 下一篇: Android SystemServer