启动zygote后执行了app_main.cpp文件中的main函数,再通过AndroidRuntime.cpp中的start函数创建虚拟机、添加android所需的JNI注册、通过反射调用到ZygoteInit.java文件中的main函数。
本文以Android 13代码为例。
1,在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中
public static void main(String[] argv) {
ZygoteServer zygoteServer = null;
Runnable caller; //声明一个Runnable类型的变量caller,用于存储从zygoteServer.runSelectLoop返回的Runnable对象,该对象代表需要执行的新进程任务。
boolean startSystemServer = false;
String zygoteSocketName = "zygote";
for (int i = 1; i < argv.length; i++) { //解析app_main.cpp传的参数
if ("start-system-server".equals(argv[i])) { //命令行参数指定了启动system server
startSystemServer = true;
}
}
final boolean isPrimaryZygote = zygoteSocketName.equals(Zygote.PRIMARY_SOCKET_NAME); //public static final String PRIMARY_SOCKET_NAME = "zygote";
preload(bootTimingsTraceLog); //zygote preload预加载
zygoteServer = new ZygoteServer(isPrimaryZygote); //创建socket服务,server端
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer); //在main函数中forkSystemServer,启动systemserver进程
// {@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); //循环等待fork出其它应用进程,即在Zygote的主循环中等待来自客户端的孵化新进程的请求,比如等待ams请求创建新的进程。
}
static void preload(TimingsTraceLog bootTimingsTraceLog) {
preloadClasses(); // 加载系统类
preloadResources(); // 加载系统资源
maybePreloadGraphicsDriver(); // 预加载opengl
preloadSharedLibraries(); // 加载共享库,android,compiler_rt,jnigraphics
warmUpJcaProviders(); // 初始化jca安全相关参数
}
private static Runnable forkSystemServer(String abiList, String socketName,ZygoteServer zygoteServer) {
pid = Zygote.forkSystemServer( //调用Zygote类的forkSystemServer
parsedArgs.mUid, parsedArgs.mGid,
parsedArgs.mGids,
parsedArgs.mRuntimeFlags,
null,
parsedArgs.mPermittedCapabilities,
parsedArgs.mEffectiveCapabilities);
if (pid == 0) { //PID为0,表示当前代码在子进程中执行。此时,会关闭Zygote服务器的socket连接,并调用handleSystemServerProcess方法处理System Server进程的启动逻辑。
zygoteServer.closeServerSocket();
return handleSystemServerProcess(parsedArgs); //返回处理系统服务进程
}
}
上面的代码通过调用Zygote.forkSystemServer走到了Zygote.java文件的forkSystemServer函数。
2,在frameworks/base/core/java/com/android/internal/os/Zygote.java中
static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
ZygoteHooks.preFork();
int pid = nativeForkSystemServer(
uid, gid, gids, runtimeFlags, rlimits,
permittedCapabilities, effectiveCapabilities); //调用native forkSystemServer
// Set the Java Language thread priority to the default value for new apps.
Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
ZygoteHooks.postForkCommon();
return pid;
}
private static native int nativeForkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);
上面的代码调用本地代码nativeForkSystemServer,将会进一步地走到其实现函数com_android_internal_os_Zygote_nativeForkSystemServer中调用linux的fork函数。首先需要看这个本地函数nativeForkSystemServer是在哪里注册的。
3,在frameworks/base/core/jni/com_android_internal_os_Zygote.cpp文件中
static const JNINativeMethod gMethods[] = {
//每个JNINativeMethod结构体包含三个字段:name:Java中本地方法的名称。signature:该方法的签名,描述了方法的参数类型和返回类型。fnPtr:指向本地实现函数的指针,即C/C++中实现的函数地址。
{"nativeForkSystemServer", "(II[II[[IJJ)I",(void*)com_android_internal_os_Zygote_nativeForkSystemServer},
//签名"(II[II[[IJJ)I"由以下几部分组成:(:方法的参数列表开始。II:前两个参数都是int类型。[II:第三个参数是一个一维的int数组(即int[])。[[I:第四个参数是一个二维的int数组(即int[][])。JJ:接下来的两个参数都是long类型(在JNI中,Java的long类型被表示为J)。):方法的参数列表结束。I:方法的返回类型是int。
}
上面的JNINativeMethod结构体gMethods是在下面的函数中调用的
int register_com_android_internal_os_Zygote(JNIEnv* env) {
gZygoteClass = MakeGlobalRefOrDie(env, FindClassOrDie(env, kZygoteClassName)); //使用FindClassOrDie函数查找com.android.internal.os.Zygote类,并通过MakeGlobalRefOrDie函数获取该类的全局引用,存储在全局变量gZygoteClass中。这样做是为了防止Java侧的类被垃圾回收器回收,从而确保在C/C++中可以持续访问该类。
gCallPostForkSystemServerHooks = GetStaticMethodIDOrDie(env, gZygoteClass, "callPostForkSystemServerHooks","(I)V");
gCallPostForkChildHooks = GetStaticMethodIDOrDie(env, gZygoteClass, "callPostForkChildHooks", "(IZZLjava/lang/String;)V");
gZygoteInitClass = MakeGlobalRefOrDie(env, FindClassOrDie(env, kZygoteInitClassName)); //查找com.android.internal.os.ZygoteInit类并获取其全局引用,存储在gZygoteInitClass中。
gGetOrCreateSystemServerClassLoader = GetStaticMethodIDOrDie(env, gZygoteInitClass, "getOrCreateSystemServerClassLoader","()Ljava/lang/ClassLoader;");
gPrefetchStandaloneSystemServerJars = GetStaticMethodIDOrDie(env, gZygoteInitClass, "prefetchStandaloneSystemServerJars","()V");
RegisterMethodsOrDie(env, "com/android/internal/os/Zygote", gMethods, NELEM(gMethods)); //注册了与com.android.internal.os.Zygote相关的本地方法,这些方法的实现在C/C++中定义,但可以在Java中通过native声明来调用
return JNI_OK;
}
而gMethods中定义的nativeForkSystemServer函数对应的本地实现函数com_android_internal_os_Zygote_nativeForkSystemServer的实现如下。
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 permitted_capabilities,
jlong effective_capabilities) { //native函数forkSystemServer
pid_t pid = zygote::ForkCommon(env, true,fds_to_close,fds_to_ignore,true); //通过调用zygote::ForkCommon函数来创建系统服务进程。这个函数会执行fork操作,并处理与进程创建相关的各种准备工作。
return pid;
}
pid_t zygote::ForkCommon(JNIEnv* env, bool is_system_server,const std::vector<int>& fds_to_close,const std::vector<int>& fds_to_ignore,bool is_priority_fork,bool purge) {
auto fail_fn = std::bind(zygote::ZygoteFailure, env, is_system_server ? "system_server" : "zygote",
nullptr, _1); //通过std::bind创建一个失败处理函数fail_fn,这个函数会在fork操作失败时被调用,用于记录错误信息。
BlockSignal(SIGCHLD, fail_fn); //阻塞SIGCHLD信号:在fork操作之前,通过BlockSignal函数阻塞SIGCHLD信号。这是因为在fork之后,子进程会继承父进程的信号处理设置,如果此时SIGCHLD信号的处理器尝试进行日志记录等操作,可能会因为文件描述符已经被关闭而导致问题。
if (gOpenFdTable == nullptr) {
gOpenFdTable = FileDescriptorTable::Create(fds_to_ignore, fail_fn); //如果是Zygote进程中的第一次fork,通过FileDescriptorTable::Create函数创建一个新的文件描述符表gOpenFdTable,该表会检查并允许列表中指定的文件描述符。
} else {
gOpenFdTable->Restat(fds_to_ignore, fail_fn); //如果不是第一次fork,则通过gOpenFdTable->Restat函数重新检查已打开的文件描述符,确保它们没有发生变化。
}
if (purge) {
mallopt(M_PURGE, 0); //如果purge参数为true,则通过mallopt(M_PURGE, 0)函数尝试清理未使用的内存,以减少与子进程共享的内存量,从而减少fork后子进程私有脏页的数量。
}
pid_t pid = fork(); //调用fork函数,通过fork函数创建新的进程。fork返回后,父进程中返回新创建的子进程的PID,子进程中返回0。
UnblockSignal(SIGCHLD, fail_fn); //通过UnblockSignal函数恢复SIGCHLD信号的处理。
return pid;
}
注册native方法的函数register_com_android_internal_os_Zygote定义在AndroidRuntime.cpp中的gRegJNI数组中。
4,在frameworks/base/core/jni/AndroidRuntime.cpp中
static const RegJNIRec gRegJNI[] = {
REG_JNI(register_com_android_internal_os_Zygote),
REG_JNI(register_com_android_internal_os_ZygoteInit),
}
int AndroidRuntime::startReg(JNIEnv* env) {
if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) { //JNI方法通过register_jni_procs完成注册
env->PopLocalFrame(NULL);
return -1;
}
}
上面的startReg函数又是在AndroidRuntime.cpp中的start函数中调用的。
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote) {
JNIEnv* env;
if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) { //创建虚拟机
return;
}
onVmCreated(env);
/*
* Register android functions.
*/
if (startReg(env) < 0) { //注册android常用的jni
ALOGE("Unable to register all android natives\n");
return;
}
}
而AndroidRuntime类的start方法则是由app_main文件中main方法调用的,这样也就按流程逆推到zygote的启动了。