zygote启动过程中涉及到以下模块:
- app_process
- zygote
- USAP
- socket
- FileDescriptor (FD)
- AndroidRuntime
- AppRuntime (定义于app_process模块,继承自AndroidRuntime。)
init进程启动zygote进程:
#init.zygote32_64.rc
service zygote /system/bin/app_process32 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygoteclass mainpriority -20user rootgroup root readproc reserved_disksocket zygote stream 660 root systemsocket usap_pool_primary stream 660 root systemonrestart exec_background - system system -- /system/bin/vdc volume abort_fuseonrestart write /sys/power/state ononrestart restart audioserveronrestart restart cameraserveronrestart restart mediaonrestart restart netdonrestart restart wificondwritepid /dev/cpuset/foreground/tasksservice zygote_secondary /system/bin/app_process64 -Xzygote /system/bin --zygote --socket-name=zygote_secondaryclass mainpriority -20user rootgroup root readproc reserved_disksocket zygote_secondary stream 660 root systemsocket usap_pool_secondary stream 660 root systemonrestart restart zygotewritepid /dev/cpuset/foreground/tasks
一、绑定socket
init.zygote32_64.rc脚本中分别定义了32位(primary)和64位(secondary)zygote进程的启动参数,在/dev/socket/下创建UNIX域的socket,并把socket的fd传给对应的进程。
“ANDROID_SOCKET_zygote”,"ANDROID_SOCKET_zygote_secondary"分别为两个zygote的socket在环境变量中对应的key值,通过key获取对应的value,创建FileDescriptor对象。通过 “ls -l /proc/${pid}/fd” 命令可查看对应进程的所有fd指向的符号链接。
static LocalServerSocket createManagedSocketFromInitSocket(String socketName) {int fileDesc;final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName; // ANDROID_SOCKET_zygotetry {String env = System.getenv(fullSocketName);fileDesc = Integer.parseInt(env); // env="20"} catch (RuntimeException ex) {throw new RuntimeException("Socket unset or invalid: " + fullSocketName, ex);}try {FileDescriptor fd = new FileDescriptor();fd.setInt$(fileDesc);return new LocalServerSocket(fd);} catch (IOException ex) {throw new RuntimeException("Error building socket from file descriptor: " + fileDesc, ex);}}
二、zygote启动
app_process进程:
//app_main.cpp
int main(int argc, char* const argv[])
{//...if (zygote) {runtime.start("com.android.internal.os.ZygoteInit", args, zygote);} else if (className) {runtime.start("com.android.internal.os.RuntimeInit", args, zygote);}
}
变量runtime是AppRuntime对象,调用AndoridRuntime对象start()方法:
//AndroidRuntime.cpp
/** Start the Android runtime. This involves starting the virtual machine* and calling the "static void main(String[] args)" method in the class* named by "className".** Passes the main function two arguments, the class name and the specified* options string.*/
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{//.../* start the virtual machine * 1.启动Java虚拟机。*/JniInvocation jni_invocation;jni_invocation.Init(NULL);JNIEnv* env;if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {return;}onVmCreated(env);/** Register android functions.* 2.注册JNI方法。*/if (startReg(env) < 0) {ALOGE("Unable to register all android natives\n");return;}/** Start VM. This thread becomes the main thread of the VM, and will* not return until the VM exits.* 3.启动对应类的静态 main()。*/jmethodID startMeth = env->GetStaticMethodID(startClass, "main","([Ljava/lang/String;)V");env->CallStaticVoidMethod(startClass, startMeth, strArray);
}
启动zygote时className变量是"com.android.internal.os.ZygoteInit",查看其main()方法:
//ZygoteInit.java
public static void main(String[] argv) {//.../** 1. 执行预加载。*/if (!enableLazyPreload) {preload(bootTimingsTraceLog);}/** 2. 实例化ZygoteServer()对象,* 1).初始化 Zygote server socket。* 2).初始化 USAP pool server socket。* 3).初始化 USAP pool event FD。*/zygoteServer = new ZygoteServer(isPrimaryZygote);/** 3. 启动 system_server进程,*/if (startSystemServer) {Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);// {@code r == null} in the parent (zygote) process, and {@code r != null} in the// child (system_server) process.if (r != null) {r.run();return;}}/** 4. 循环接受处理 socket 事件。*/// The select loop returns early in the child process after a fork and// loops forever in the zygote.caller = zygoteServer.runSelectLoop(abiList);
}
三、处理socket消息
ZygoteServer接收到socket消息后,调用processOneCommand方法解析消息参数。
//ZygoteServer.javaZygoteConnection connection = peers.get(pollIndex);final Runnable command = connection.processOneCommand(this);
最终在Zygote类的forkAndSpecialize方法中调用nativeForkAndSpecialize()方法fork新进程:
//Zygote.java
static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,boolean isTopApp, String[] pkgDataInfoList, String[] whitelistedDataInfoList,boolean bindMountAppDataDirs, boolean bindMountAppStorageDirs) {ZygoteHooks.preFork();int pid = nativeForkAndSpecialize(uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,fdsToIgnore, startChildZygote, instructionSet, appDataDir, isTopApp,pkgDataInfoList, whitelistedDataInfoList, bindMountAppDataDirs,bindMountAppStorageDirs);ZygoteHooks.postForkCommon();return pid;}
重点查看ZygoteConnection类的processOneCommand()方法:
在nativeForkAndSpecialize()方法fork新进程后,通过判断返回的pid是否大于0区分母子进程。
fork是类Unix操作系统上创建进程的主要方法。fork用于创建子进程(等同于当前进程的副本),新的进程要通过老的进程复制自身得到,这就是fork!
fork作为一个函数被调用。这个函数会有两次返回,将子进程的PID返回给父进程,0返回给子进程。(如果小于0,则说明创建子进程失败)。
//ZygoteConnection.java
Runnable processOneCommand(ZygoteServer zygoteServer) {//...pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mIsTopApp,parsedArgs.mPkgDataInfoList, parsedArgs.mWhitelistedDataInfoList,parsedArgs.mBindMountAppDataDirs, parsedArgs.mBindMountAppStorageDirs);try {if (pid == 0) {// in childzygoteServer.setForkChild();zygoteServer.closeServerSocket();IoUtils.closeQuietly(serverPipeFd);serverPipeFd = null;return handleChildProc(parsedArgs, childPipeFd, parsedArgs.mStartChildZygote);} else {// In the parent. A pid < 0 indicates a failure and will be handled in// handleParentProc.IoUtils.closeQuietly(childPipeFd);childPipeFd = null;handleParentProc(pid, serverPipeFd);return null;}} finally {IoUtils.closeQuietly(childPipeFd);IoUtils.closeQuietly(serverPipeFd);}
}
所以可以看到handleChildProc()和handleParentProc()分别处理的是子进程,母进程的逻辑。
最终子进程执行zygoteInit()方法完成一个Android 应用程序的启动(初始化):
public static final Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,String[] argv, ClassLoader classLoader) {if (RuntimeInit.DEBUG) {Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");}Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");RuntimeInit.redirectLogStreams();RuntimeInit.commonInit();ZygoteInit.nativeZygoteInit();return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,classLoader);}
ZygoteInit.nativeZygoteInit(); 使支持Binder进程间通信机制。
RuntimeInit.applicationInit(); 调用ActivityThread.main()方法,启动UI线程。