2)Android Runtime的启动,它是在Init进程之后,zygote进程启动之后、初始化之前初始化的,所以此时它的入口和zygote的入口一致
//AndroidRuntime.cpp
void AndroidRuntime::start(const char* className, const Vector& options){
...
if (startVm(&mJavaVM, &env) != 0) {//启动虚拟机
return;
}
onVmCreated(env);//创建VM之后释放slashClassName的内存
if (startReg(env) < 0) {//注册Android JNI函数
ALOGE("Unable to register all android natives\n");
return;
}
...
char* slashClassName = toSlashClassName(className);//解析类名
jclass startClass = env->FindClass(slashClassName);//找到需要启动的java类
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
} else {//得到指定类中指定方法的ID,这里得到的是RuntimeInit.main()的方法ID
jmethodID startMeth = env->GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V");
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'\n", className);
} else {//调用上面得到的方法ID和相关参数,即调用Java类ZygoteInit.main();
env->CallStaticVoidMethod(startClass, startMeth, strArray);
...
}
}
...
}
3)系统建立AndroidRuntime的时候,创建Java虚拟机,并将系统中一些JNI函数注册到Java虚拟机中,
1)ZygoteInit.main(...)做的事情
public class ZygoteInit {
...
public static void main(String argv[]) {
// Mark zygote start. This ensures that thread creation will throw an error.
ZygoteHooks.startZygoteNoThreadCreation();
try {
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygoteInit");
RuntimeInit.enableDdms();//开启Ddms监听,监听Ddms消息
// Start profiling the zygote initialization.
SamplingProfilerIntegration.start();//启动性能统计
boolean startSystemServer = false;
String socketName = "zygote";
String abiList = null;
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.");
}
registerZygoteSocket(socketName);//创建了一个socket接口,用来和ActivityManagerService通讯
...
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START, SystemClock.uptimeMillis());
/*
* http://blog.csdn.net/fu_kevin0606/article/details/54097031
* 在Android系统中有很多的公共资源,所有的程序都会需要。而Zygote创建应用程序进程过程,复制自身进程地址空间作为应用程序进程的地址空间,
* 因此在Zygote进程中加载的类和资源都可以共享给所有由Zygote进程孵化的应用程序。
* 所以就可以在Zygote中对公共类与资源进行加载,当应用程序启动时只需要加载自身特有的类与资源就行了,提高了应用软件的启动速度
*/
preload();//预加载classes、预加载resources、预加载openGL、预加载共享类库、文本资源
...
// Finish profiling the zygote initialization.
SamplingProfilerIntegration.writeZygoteSnapshot();//结束统计并生成结果文件
...
gcAndFinalize();
...
// Zygote process unmounts root storage spaces.
Zygote.nativeUnmountStorageOnInit();
ZygoteHooks.stopZygoteNoThreadCreation();
if (startSystemServer) {
startSystemServer(abiList, socketName);//Fork一系列系统进程
}
/*
* 开始Zygote进程的死循环,在前面创建的socket接口上等待ActivityManagerService请求创建新的应用程序进程
* Socket的监听方式为使用Linux系统调用select()函数监听Socket文件描述符,
* 当该文件描述符上有数据时,自动触发中断,在中断处理函数中去读取文件描述符中的数据
*/
runSelectLoop(abiList);
closeServerSocket();
} catch (MethodAndArgsCaller caller) {
caller.run();
} catch (RuntimeException ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throw ex;
}
}
...
/** fork系统进程
* Prepare the arguments and fork for the system server process.
*/
private static boolean startSystemServer(String abiList, String socketName)
throws MethodAndArgsCaller, RuntimeException {
long capabilities = posixCapabilitiesAsBits(
OsConstants.CAP_IPC_LOCK,
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
);
/* Containers run without this capability, so avoid setting it in that case */
if (!SystemProperties.getBoolean(PROPERTY_RUNNING_IN_CONTAINER, false)) {
capabilities |= posixCapabilitiesAsBits(OsConstants.CAP_BLOCK_SUSPEND);
}
/* 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,3009,3010",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
"com.android.server.SystemServer",//这个SystemServer的run()内会创建ActivityManagerService
};
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
parsedArgs = new ZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
/* Request to fork the system server process */
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 */
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
handleSystemServerProcess(parsedArgs);
}
return true;
}
Zygote启动时初始化的公共资源,在创建子进程时共享给子进程,提高了app启动速度
在Android系统中有很多的公共资源,所有的程序都会需要。而Zygote创建应用程序进程过程,复制自身进程地址空间作为应用程序进程的地址空间, 因此在Zygote进程中加载的类和资源都可以共享给所有由Zygote进程孵化的应用程序。
所以就可以在Zygote中对公共类与资源进行加载,当应用程序启动时只需要加载自身特有的类与资源就行了,提高了应用软件的启动速度
2)Zygote如何fork新进程,点击桌面应用图标时如何创建新的进程
当点击Launcher里的应用程序去启动一个新的应用程序进程时,这个请求会到达framework层的核心服务ActivityManagerService中,当AMS收到这个请求后,它通过调用Process类发出一个"孵化子进程"的Socket请求,而Zygote监听到这个请求后就立刻fork一个新的进程出来。