zygote是有init进程根据init.rc配置文件创建的。本来是执行名为app_process的程序后替换为zygote。app_process对应的源程序为App_main.cpp文件。
1、App_main.cpp
[–>App_main.cpp]
int main(int argc, char* const argv[])
{
if (!className.isEmpty()) {
......
//不是zygote模式时做一些设置,为调用RuntimeInit时使用
}else {
......
//在zygote模式下做一些设置,主要是一些参数的设置已传给后面启动zygote使用
}
......
if (!niceName.isEmpty()) {
......
//改写进程名字,即把app_process改为zygote
set_process_name(niceName.string());
}
}
if (zygote) {
//在zygote模式下调用ZygoteInit
runtime.start("com.android.internal.os.ZygoteInit", args);
} else if (className) {
//在非zygote模式下调用RuntimeInit
runtime.start("com.android.internal.os.RuntimeInit", args);
} else {
.....
}
App_main主要功能是调用了AppRuntime.start()这个函数以启动zygote。
2、AndroidRuntime.cpp
在App_main.main中调用了runtime.start函数,AppRuntime继承了AndroidRuntime,但它却没有覆盖基类的start方法,所以runtime.start其实是调用的AndroidRuntime.start方法。
[–>AndroidRuntime.cpp]
void AndroidRuntime::start(const char* className, const Vector<String8>& options)
{
.....
//设置ANDROID_ROOT环境变量
const char* rootDir = getenv("ANDROID_ROOT");
if (rootDir == NULL) {
rootDir = "/system";
.....
setenv("ANDROID_ROOT", rootDir, 1);
}
.....
//创建虚拟机
if (startVm(&mJavaVM, &env) != 0) {
return;
}
.....
//注册JNI
if (startReg(env) < 0) {
.....
}
.....
//通过反射机制调用
//com.android.internal.os.zygoteInit.java的main函数
jmethodID startMeth = env->GetStaticMethodID(startClass, "main","([Ljava/lang/String;)V");
.....
env->CallStaticVoidMethod(startClass, startMeth, strArray);
.....
}
在AndroidRuntime::start中主要有三个步骤
1、创建虚拟机
[–>AndroidRuntime.cpp]
int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv)
{
......
//在AndroidRuntime::startVm主要是对虚拟机的一些设置,比如设置虚拟机的heapsize大小
......
//最后会调用JNI_CreateJavaVM创建虚拟机,pEnv返回当前额JNIEnv变量
if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
......
}
......
}
2、注册JNI函数,通过 AndroidRuntime::startReg方法
3、通过反射机制调用ZygoteInit.main方法。
3、ZygoteInit.java
[–>ZygoteInit.java]
public static void main(String argv[]) {
.....
//注册zygote用的socket
registerZygoteSocket(socketName);
.....
//加载类和各种资源
preload();
.....
//启动SystemServer进程
startSystemServer(abiList, socketName);
.....
//监听zygote请求
runSelectLoop(abiList);
.....
}
其重要内容有一下几点
- 注册zygote用的socket,zygote与其他进程通信并没有使用Binder而是socket。
- 加载类和资源。会在在很多系统启动所需的类,以及相应的一些启动所需的资源。
- 创建系统服务system_server,启动一些系统核心程序 。
- 监听zygote的socket请求,一旦有客户请求就会调用相应的函数进行处理。
4、SystemServer
SystemServer子进程的启动方式
[–>ZygoteInit.java]
private static boolean startSystemServer(String abiList, String socketName){
......
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
......
if (pid == 0) {
......
handleSystemServerProcess(parsedArgs);
......
}
}
在startSystemServer方法中通过forkSystemServer创建了SystemServer进程。SystemServer子进程会调用handleSystemServerProcess来处理自己的任务,在handleSystemServerProcess关键是会调用 RuntimeInit.zygoteInit();
RuntimeInit主要工作如下
[–>RuntimeInit.java]
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)throws ZygoteInit.MethodAndArgsCaller {
......
//native层初始化
nativeZygoteInit();
......
applicationInit(targetSdkVersion, argv, classLoader);
......
}
private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)throws ZygoteInit.MethodAndArgsCaller {
......
//调用com.android.server.SystemServer.main方法
invokeStaticMain(args.startClass, args.startArgs, classLoader);
......
}
所以启动的SystemServer子进程会调用nativeZygoteInit();进行native层的初始化,以及调用invokeStaticMain启动SystemServer中的main方法。分别主要任务如下
- nativeZygoteInit是一个native函数,主要用来与Binder机制建立连接,这样SystemServer就能够使用Binder了。
- invokeStaticMain中是通过抛出异常来启动SystemServer中的main方法的。Zygote的main方法会截获这个异常,并调用caller.run();来启动SystemServer.main。
Zygote分裂产生SystemServer,起始就是为了调用com.android.server.SystemServer里的main方法,代码如下
[–>SystemServer.java]
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
.....
//为线程
Looper.prepareMainLooper();
.....
//加载android_servers库,以及初始化一些本地服务
System.loadLibrary("android_servers");
nativeInit();//在这里面可能还把本线程加入Binder通信中,具体有没有我没去看源码。
.....
//创建系统服务,就是启动framework中的各种服务如ActivityManager就是在这个时候启动的
startBootstrapServices();
startCoreServices();
startOtherServices();
.....
Looper.loop();
}
综上,SystemServer个人感觉最重要的任务就是创建启动系统所需的一些系统服务。
5、Zygote分裂
Zygote的主要任务就是进行分裂的,每当有新的应用启动的时候,就会进行自动分裂,这样即可以减少系统的开销,又可以加快应用启动的速度。
前面以说道Zygote已经先分裂出了SystemServer,并调用runSelectLoop监听客服请求。那么客服端是怎么发送请求的呢?以ActivityManagerService发送请求为例,这个服务也是有SystemServer创建的。ActivityManagerService经过一些列的调用会最终调用到Process.zygoteSendArgsAndGetResult方法,代码如下
[–>Process.java]
private static ProcessStartResult zygoteSendArgsAndGetResult(ZygoteState zygoteState, ArrayList<String> args)
throws ZygoteStartFailedEx {
.....
//这里是连接上Zygote的socket接口,zygoteState是个内部类,里面包含了一个connect方法用于连接socket
final BufferedWriter writer = zygoteState.writer;
.....
//对连接上的socket进行写操作,即向runSelectLoop发送请求。
writer.write(arg);
writer.newLine();
......
}
接下来看看runSelectLoop是怎么响应请求的。
[–>ZygoteInit.java]
private static void runSelectLoop(String abiList){
.....
//获取Socket连接
ZygoteConnection newPeer = acceptCommandPeer(abiList);
.....
//对每个连接调用runOnce处理函数
done = peers.get(index).runOnce();
.....
}
[–>ZygoteConnection.java]
boolean runOnce(){
......
//更具请求分裂出一个子进程
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal,
parsedArgs.seInfo,parsedArgs.niceName, fdsToClose,
parsedArgs.instructionSet,parsedArgs.appDataDir);
.....
if (pid == 0) {
.....
//子进程处理函数
handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
.....
}
}
private void handleChildProc(...){
.....
ZygoteInit.invokeStaticMain(cloader, className, mainArgs);
.....
}
代码中的ZygoteInit.invokeStaticMain与RuntimeInit中的invokeStaticMain相似,ZygoteInit.main也会捕获相应异常并调用caller.run();来启动android.app.ActivityThread的main方法。
以上所写还有许多不足遗漏之处,希望以后有机会加以改进。
(不可全信,但不可不信)