Zygote进程基础介绍
Zygote中文翻译为“受精卵”,正如其名,它主要用于孵化子进程。在Android系统中有以下两种程序: 1. java应用程序,主要基于ART虚拟机,所有的应用程序apk都属于这类 2. native程序,也就是利用C或C 语言开发的程序,如bootanimation。
所有的Java应用程序进程及系统服务SystemServer进程都由Zygote进程通过Linux的fork()函数孵化出来的,这也就是为什么把它称为Zygote的原因,因为他就像一个受精卵,孵化出无数子进程,而native程序则由Init程序创建启动。Zygote进程最初的名字不是“zygote”而是“app_process”,这个名字是在Android.mk文件中定义的。
如图所示为Zygote孵化框架:
Zygote是一个C/S模型,Zygote进程作为服务端,其他进程作为客户端向它发出“孵化”请求,而Zygote接收到这个请求后就“孵化”出一个新的进程。如图所示,当点击Launcher里的应用程序图标去启动一个新的应用程序进程时,这个请求会到达框架层的核心服务ActivityManagerService中,当AMS收到这个请求后,它通过调用Process类发出一个“孵化”子进程的Socket请求,而Zygote监听到这个请求后就立刻fork一个新的进程出来。
Zygote进程的启动
Zygote进程对应的主文件为app_main.cpp,当他被Init进程启动起来之后,就会进入主文件app_main.cpp的main()函数。接下来它的main函数开始分析Zygote进程的启动:
代码语言:javascript复制int main(int argc, char* const argv[])
{
.......
while (i < argc) {
const char* arg = argv[i ];
if (strcmp(arg, "--zygote") == 0) {
zygote = true;
//说明启动的是Zygote进程
niceName = ZYGOTE_NICE_NAME;
//ZYGOTE_NICE_NAME字符串内容就是“Zygote”,此处已被换名字
} else if (strcmp(arg, "--start-system-server") == 0) {
startSystemServer = true;
//在init.rc里配置了前面的这些参数,而Zygote进程启动的时候,
//Init进程会传过来这些参数,所以此处把变量startSystemServer
//设置为true代表启动SystemServer
} else if (strcmp(arg, "--application") == 0)
.......
}
......
if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
//zygote为true代表的是Zygote进程,也就是说现在正在启动的是Zygote进程,
//我们知道Zygote进程用于孵化子进程,Zygote进程孵化子进程是通过自己的资源赋值一份,
//来fork一个新的子进程,也就是说子进程也会进入这个文件的main函数,因此,
//这里的main函数被调用并不只是Zygote启动的时候被调用。这里通过zygote这个变量来区分,
//如果是Zygote进程本身,就会进入到if里,否则就会进入到下面的else if里,代表字进程启动。
} else if (className) {
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
} else {
.......
}
}
main()函数最后调用runtime的start()函数,runtime是一个AppRuntime对象,看看AppRuntime类:
代码语言:javascript复制class AppRuntime : public AndroidRuntime
{
.......
}
AppRuntime类继承AndroidRuntime类,因此前面调用的runtime的start()函数就会进入AndroidRuntime的start()函数,下面看看该函数:
代码语言:javascript复制void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
......
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
//启动VM
if (startVm(&mJavaVM, &env, zygote) != 0) {
return;
}
onVmCreated(env);
//注册JNI函数
if (startReg(env) < 0) {
ALOGE("Unable to register all android nativesn");
return;
}
....
//className由上一步传递过来,“com.android.internal.os.ZygoteInit”或者“com.android.internal.os.RuntimeInit”
char* slashClassName = toSlashClassName(className != NULL ? className : "");
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'n", slashClassName);
} else {
//表明要调用的是类的main()函数
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'n", className);
} else {
//调用ZygoteInit的main()函数或RuntimeInit的main()函数
env->CallStaticVoidMethod(startClass, startMeth, strArray);
.......
}
AndroidRuntime的start()函数主要做了以下三件事情: 1. 调用startVM()函数启动虚拟机 2. 调用startReg()函数注册JNI方法 3. 调用com.android.internal.os.ZygoteInit类的main()函数(若是子进程,则调用com.android.internal.os.RuntimeInit的main()函数,从而基本结束初始化。而Zygote进程的main函数则还有以下的会讲到的5项工作)
下面一一介绍三个函数的具体工作:
启动虚拟机
通过调用startVM()函数启动虚拟机:
代码语言:javascript复制int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote)
{
......
//通过调用JNI_CreateJavaVM()创建虚拟机,如果对这个感兴趣,可以去研究下art虚拟机
if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
ALOGE("JNI_CreateJavaVM failedn");
return -1;
}
......
}
注册JNI方法
在Android中,Java世界要调用native世界的函数就要用JNI机制,并且在Android系统中也大量使用JNI机制,Android系统通过如下的startReg()函数去注册:
代码语言:javascript复制/*static*/ int AndroidRuntime::startReg(JNIEnv* env)
{
......
if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
env->PopLocalFrame(NULL);
return -1;
}
.......
}
startReg()函数通过调用register_jni_procs()函数去进一步注册,传递的值是gRegJNI数组,原生Android6.0版本该数组超过130个,具体如下:
代码语言:javascript复制static const RegJNIRec gRegJNI[] = {
REG_JNI(register_com_android_internal_os_RuntimeInit),
REG_JNI(register_com_android_internal_os_ZygoteInit),
REG_JNI(register_android_os_SystemClock),
REG_JNI(register_android_util_EventLog),
REG_JNI(register_android_util_Log),
REG_JNI(register_android_util_MemoryIntArray),
REG_JNI(register_android_util_PathParser),
REG_JNI(register_android_app_admin_SecurityLog),
REG_JNI(register_android_content_AssetManager),
REG_JNI(register_android_content_StringBlock),
REG_JNI(register_android_content_XmlBlock),
REG_JNI(register_android_text_AndroidCharacter),
REG_JNI(register_android_text_StaticLayout),
REG_JNI(register_android_text_AndroidBidi),
REG_JNI(register_android_view_InputDevice),
REG_JNI(register_android_view_KeyCharacterMap),
REG_JNI(register_android_os_Process),
REG_JNI(register_android_os_SystemProperties),
REG_JNI(register_android_os_Binder),
REG_JNI(register_android_os_Parcel),
......
}
上面所列的JNI都通过register_jni_procs()函数来注册:
代码语言:javascript复制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 NDEBUG
ALOGD("----------!!! %s failed to loadn", array[i].mName);
#endif
return -1;
}
}
return 0;
}
通过循环对所有的JNI函数进行注册。。。
调用ZygoteInit类的main()
ZygoteInit是一个Java类,我们终于走到了Java世界,看看该main()方法:
代码语言:javascript复制 public static void main(String argv[]) {
......
try {
......
boolean startSystemServer = false;
String socketName = "zygote";
String abiList = null;
boolean enableLazyPreload = false;
for (int i = 1; i < argv.length; i ) {
if ("start-system-server".equals(argv[i])) {
startSystemServer = true;
........
zygoteServer.registerServerSocket(socketName);
.......
preload(bootTimingsTraceLog);
.......
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, socketName, 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;
}
}
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
.....
} finally {
zygoteServer.closeServerSocket();
}
if (caller != null) {
caller.run();
}
}
ZygoteInit类的main()方法主要做了以下5项工作: 1. 调用ZygoteServer类的registerServerSocket()方法创建一个Zygote的Socket接口,用来和AMS通信 2. 调用preload()预加载类和资源 3. 调用forkSystemServer()函数来启动SystemServer进程,r.run()启动其main()方法 4. 调用ZygoteServer类的runSelectLoop()函数在前面创建的Socket接口上进入一个无限循环,等待核心服务AMS请求创建新的应用程序进程。 5. 调用caller.run()方法,启动子进程直接进入子进程的main()方法(非system_server进程,该进程由r.run()启动main()方法)
下面一一讲解着五项工作的内容:
registerServerSocket()
通过调用ZygoteServer类的registerServerSocket()方法来创建一个Java层的LocalServerSocket对象,目的是等待创建新的应用程序进程请求:
代码语言:javascript复制 void registerServerSocket(String socketName) {
if (mServerSocket == null) {
.......
try {
FileDescriptor fd = new FileDescriptor();
fd.setInt$(fileDesc);
mServerSocket = new LocalServerSocket(fd);
} catch (IOException ex) {
.......
}
}
}
preload()预加载类与资源
代码语言:javascript复制 static void preload(BootTimingsTraceLog bootTimingsTraceLog) {
.......
//加载类,通过反射加载framework下的preload-classes文件中的类
preloadClasses();
......
//加载资源,加载framework-res-apk的资源
preloadResources();
//这两个方法比较耗时,Android启动时间慢,这是其中一个原因,加载的类和资源太多了,导致时间过长。
//提供一种思路去优化开机速度,既然这两个方法时间过长,就单独开一个线程去执行它,不要放在这个主线程里,可以试试
......
//加载OpenGL()
preloadOpenGL();
.....
//加载共享库
preloadSharedLibraries();
.....
}
既然加载这些类和资源这么耗时间,为什么还要预加载: 应用程序都从Zygote孵化出来,应用程序都会继承Zygote的所有内容,如果在Zygote启动的时候加载这些类和资源,这些孵化的应用程序就继承Zygote的类和资源,这样启动引用程序的时候就不需要加载类和资源了,启动的速度就会快很多。开机的次数不多,但是启动应用程序的次数非常多。
启动SystemServer进程
后续我们将分析启动SystemServer进程,主要是比较启动SystemServer进程与启动普通应用程序进程的区别。
runSelectLoop()函数进入无限循环
代码语言:javascript复制 Runnable runSelectLoop(String abiList) {
.......
while (true) {
if (i == 0) {
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
ZygoteConnection connection = peers.get(i);
final Runnable command = connection.processOneCommand(this);
......
}
.......
}
在无限循环中,如果变量i==0,表示Zygote Socket服务还没有准备好;当i!=0时,表示正在等待客户端来连接“Zygote”这个Socket。当有孵化子进程的请求时,就会调用ZygoteConnection类的processOneCommand()函数来创建子进程。
caller.run()函数
我们将在启动应用程序进程的时候分析caller.run()函数。
SystemServer进程
启动syetem_server进程
从上面的学习可知,启动系统服务system_server进程从ZygoteInit.java的main()方法调用forkSystemServer()方法开始,先看看该方法:
代码语言:javascript复制 private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
.....
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",
"--capabilities=" capabilities "," capabilities,
"--nice-name=system_server",
"--runtime-args",
"com.android.server.SystemServer",
};
.......
try {
......
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.runtimeFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
.......
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
return handleSystemServerProcess(parsedArgs);
}
return null;
}
首先设置了system_server进程的uid。gid和groups,然后设置进程的名字为”–nice-name=system_server”。接着调用forkSystemServer()函数来fork一个新的进程,他有两个返回值,一个在当前进程中返回,另一个在新创建的进程中返回,在当前进程中返回值是新创建的pid值,而新创建进程中的返回值是0。 如果pid==0,表示已经进入SystemServer子进程,于是先调用zygoteServer.closeServerSocket()关闭“Zygote”socket,由于Zygote启动过程中创建一个“Zygote”Socket。而系统服务进程system_server也继承了Socket,不用所以close它。接着调用了handleSystemServerProcess()方法:
代码语言:javascript复制 private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
.......
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
.......
}
主要调用了ZygoteInit.zygoteInit()方法:
代码语言:javascript复制 public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
RuntimeInit.redirectLogStreams();
RuntimeInit.commonInit();
ZygoteInit.nativeZygoteInit();
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
zygoteInit()方法主要调用了ZygoteInit.nativeZygoteInit()和RuntimeInit.applicationInit()这两个方法: - nativeZygoteInit()主要执行Binder驱动程序初始化的相关工作,它调用之后system_server进程就可以进行Binder进程通信(),是个native方法。 - 调用applicationInit()方法主要是为了进入SystemServer.java的main()方法
接下来看看RuntimeInit.applicationInit()方法:
代码语言:javascript复制 protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
........
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
代码语言:javascript复制 private static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;
try {
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " className,
ex);
}
Method m;
try {
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
..........
return new MethodAndArgsCaller(m, argv);
}
可以看出applicationInit()方法调用findStaticMain()方法,而该方法通过反射获取system-server的main()方法后返回一个MethodAndArgsCaller,这是一个Runnable:
代码语言:javascript复制 static class MethodAndArgsCaller implements Runnable {
/** method to call */
private final Method mMethod;
/** argument array */
private final String[] mArgs;
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
public void run() {
try {
mMethod.invoke(null, new Object[] { mArgs });
} catch (IllegalAccessException ex) {
.......
}
}
}
可见通过反射调用main()方法,但返回到哪呢?其实在上面的ZygoteInit类的main()方法中,在创建完system_server后直接调用,如下ZygoteInit类的main()方法代码所示,Runnable类型的r调用r.run()方法:
代码语言:javascript复制 public static void main(String argv[]) {
......
try {
........
zygoteServer.registerServerSocket(socketName);
.......
preload(bootTimingsTraceLog);
.......
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, socketName, 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;
}
}
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
.....
} finally {
zygoteServer.closeServerSocket();
}
if (caller != null) {
caller.run();
}
}
SystemServer fork新进程
Init进程、Zygote进程和SystemServer进程都非常重要,因为任何一个死机否会出现重启。从上面的讲解中可知,SystemServer系统服务的启动从ZygoteInit类的forkSystemServer()方法开始:
代码语言:javascript复制 private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
.....
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",
"--capabilities=" capabilities "," capabilities,
"--nice-name=system_server",
"--runtime-args",
"com.android.server.SystemServer",
};
.......
try {
......
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.runtimeFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
.......
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
return handleSystemServerProcess(parsedArgs);
}
return null;
}
主要调用了两个方法,Zygote.forkSystemServer()和handleSystemServerProcess(),上面讲解了handleSystemServerProcess(),现在主要分析Zygote.forkSystemServer():
代码语言:javascript复制 public static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
VM_HOOKS.preFork();
// Resets nice priority for zygote process.
resetNicePriority();
int pid = nativeForkSystemServer(
uid, gid, gids, runtimeFlags, rlimits, permittedCapabilities, effectiveCapabilities);
// Enable tracing as soon as we enter the system_server.
if (pid == 0) {
Trace.setTracingEnabled(true);
}
VM_HOOKS.postForkCommon();
return pid;
}
主要调用了nativeForkSystemServer(),这是一个native方法,对应的实现如下:
代码语言:javascript复制static jint com_android_internal_os_Zygote_nativeForkSystemServer(
JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
jint runtime_flags, jobjectArray rlimits, jlong permittedCapabilities,
jlong effectiveCapabilities) {
pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,
runtime_flags, rlimits,
permittedCapabilities, effectiveCapabilities,
MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,
NULL, NULL, NULL);
//传入了众多参数来fork一个新的进程
if (pid > 0) {
ALOGI("System server process %d has been created", pid);
gSystemServerPid = pid;
int status;
if (waitpid(pid, &status, WNOHANG) == pid) {
ALOGE("System server process %d has died. Restarting Zygote!", pid);
RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!");
}
}
return pid;
}
主要调用了ForkAndSpecializeCommon()函数:
代码语言:javascript复制static pid_t ForkAndSpecializeCommon(......) {
.....
pid_t pid = fork();
......
UnsetSigChldHandler();
......
}
主要调用了两个函数,fork()函数来创建一个新的子进程,接下来看看UnsetSigChldHandler():
代码语言:javascript复制static void SetSigChldHandler() {
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = SigChldHandler;
int err = sigaction(SIGCHLD, &sa, NULL);
if (err < 0) {
ALOGW("Error setting SIGCHLD handler: %s", strerror(errno));
}
}
SetSigChldHandler()设置了信号处理函数SigChldHandler,意思是子进程死亡之后,就会产生一个信号,Zygote进程受到该信号之后就会调用SigChldHandler()处理异常:
代码语言:javascript复制static void SigChldHandler(int /*signal_number*/) {
pid_t pid;
int status;
int saved_errno = errno;
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
........
if (pid == gSystemServerPid) {
kill(getpid(), SIGKILL);
}
}
变量gSystemServerPid表示SystemServer进程的pid,若SystemServer进程停止工作,那么首先通过getpid()来获取Zygote进程的pid,然后调用kill函数杀死它,即SystemServer停止工作之后,Zygote进程自杀,已达到Zygote与SystemServer生死与共的目的。
在Init进程的main()函数中有一个死循环,如果它的子进程Zygote停止工作,就会去重启子进程,代码如下:
代码语言:javascript复制int main(int argc,char** argv){
......
while(true){
if(!waiting_for_exec){
execute_one_command();
restart_processes();
//重启死掉的service,如果zygote死掉了,就重启Zygote。
.......
}
}
}
从这个过程可知,Init进程、Zygote进程、SystemServer进程紧密相连,任何一个都不能出问题。
SystemServer创建框架核心服务
当SystemServer启动之后,就会进入main()方法,又在它的main()方法中调用run()方法。Android系统的核心服务AMS、WMS、PMS等就是在run()方法里进行创建和初始化的,当它们创建之后,会通过ServiceManager的add_server()方法把它们加入到ServiceManager中统一管理。
代码语言:javascript复制public final class SystemServer {
.......
public static void main(String[] args) {
new SystemServer().run();
}
......
private void run() {
.....
Looper.prepareMainLooper();
//创建消息队列
System.loadLibrary("android_servers");
//加载SystemServer需要的android_servers库
createSystemContext();
//创建系统Context
......
startBootstrapServices();
startCoreServices();
startOtherServices();
//这三个方法是创建系统核心服务的实现
Looper.loop();
//进入消息循环,不止是应用程序有消息队列,SystemServer也有
}
}
run()方法主要调用了三个重要的方法,在这三个方法中创建和初始化了重要的系统服务,如AMS、WMS、PMS等等。
APP应用程序进程
前面分析了Zygote如何启动SystemServer子进程,接下来再分析Zygote如何启动其他子进程,也就是创建应用程序进程的过程,这个过程和创建SystemServer进程基本一样。当点击Launcher主界面的一个应用程序图标时,如果这个应用程序还未曾启动,就会启动它。而判断应用程序有没有启动和去启动应用程序都由核心服务AMS来做,它的startProcessLocked()方法会真正地启动应用程序子进程。
下面为AMS的startProcessLocked()方法:
代码语言:javascript复制 private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
......
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
......
ProcessStartResult startResult;
startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,app.info.dataDir, invokeWith, entryPointArgs);
}
.......
}
AMS的startProcessLocked()方法调用Process类的start()方法为应用程序创建新的进程,这里的参数entryPoint为“android.app.ActivityThread”,它是传进去的第一个参数,也就是程序初始化进程时要加载的主文件Java类。当应用进程启动之后,会把这个类加载到进程,调用它的main()方法作为应用程序进程的入口。 Process类的start()直接调用了ZygoteProcess类的start()方法,该start()方法有直接调用了ZygoteProcess类的startViaZygote()方法,下面看看该方法实现:
代码语言:javascript复制 private Process.ProcessStartResult startViaZygote(final String processClass,final String niceName,final int uid, final int gid,final int[] gids,int runtimeFlags, int mountExternal,int targetSdkVersion,String seInfo,String abi,String instructionSet,String appDataDir,String invokeWith,String[] extraArgs)throws ZygoteStartFailedEx {
ArrayList<String> argsForZygote = new ArrayList<String>();
argsForZygote.add("--runtime-args");
argsForZygote.add("--setuid=" uid);
argsForZygote.add("--setgid=" gid);
......
synchronized(mLock) {
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}
}
首先给它设置值,包括uid、gid等。这些值是应用程序在安装时系统分配好的。接着调用openZygoteSocketIfNeeded()方法来链接“zygote”Socket,链接Socket成功之后,就会调用zygoteSendArgsAndGetResult()方法来进一步处理。
先来看看openZygoteSocketIfNeeded()方法:
代码语言:javascript复制 private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
.......
if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
try {
primaryZygoteState = ZygoteState.connect(mSocket);
}
.......
}
方法中的mSocket的值是“zygote”,通过connect()方法去链接“zygote”Socket。
接着看看zygoteSendArgsAndGetResult()方法:
代码语言:javascript复制 private static Process.ProcessStartResult zygoteSendArgsAndGetResult(
ZygoteState zygoteState, ArrayList<String> args)
throws ZygoteStartFailedEx {
try {
........
final BufferedWriter writer = zygoteState.writer;
final DataInputStream inputStream = zygoteState.inputStream;
writer.write(Integer.toString(args.size()));
writer.newLine();
for (int i = 0; i < sz; i ) {
String arg = args.get(i);
writer.write(arg);
writer.newLine();
}
writer.flush();
.......
}
通过Socket写入流writer把前面传过来的那些参数写进去,Socket即ZygoteServer类的runSelectLoop()方法监听。写入这些数据之后,ZygoteServer类的runSelectLoop()方法就能被监听到。 看一下runSelectLoop()方法的关键实现代码:
代码语言:javascript复制 Runnable runSelectLoop(String abiList) {
.......
if (i == 0) {
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
ZygoteConnection connection = peers.get(i);
final Runnable command = connection.processOneCommand(this);
......
}
进入ZygoteConnection类的processOneCommand()方法后:
代码语言:javascript复制 Runnable processOneCommand(ZygoteServer zygoteServer) {
........
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.runtimeFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.instructionSet,
parsedArgs.appDataDir);
try {
if (pid == 0) {
// in child
zygoteServer.setForkChild();
zygoteServer.closeServerSocket();
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
return handleChildProc(parsedArgs, descriptors, childPipeFd);
........
}
之前启动SystemServer进程的代码有点相似。此处是通过Zygote.forkAndSpecialize()来fork新的应用进程,而启动systemserver进程是通过Zygote.forkSystemServer()来fork SystemServer进程。这里通过handleChildProc()方法处理,而之前是嗲偶用handleSystemServerProcess()来处理。通过fork新的应用程序进程之后,返回pid等于0就表示进入子进程,于是调用handleChildProc()方法进一步处理:
代码语言:javascript复制 private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,FileDescriptor pipeFd) {
........
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs,null /* classLoader */);
.......
}
到此处,后面便和上面一样的了,唯一不同的是,SystemServer进程启动之后进入的是主类SystemServer.java的main()函数,而这里应用程序启动起来后进入的是主类是ActivityThread.java的main()函数。
至此,Zygote进程以及Zygote进程启动SystemServer进程和启动应用程序进程就分析完毕了,Zygote进程为了启动SystemServer和启动应用程序进程主要做了两件事,一是初始化Binder驱动用来进行进程间通信,二是通过反射进入main()方法。