Android 12系统源码_系统启动(二)Zygote进程

前言

Zygote(意为“受精卵”)是 Android 系统中的一个核心进程,负责 孵化(fork)应用进程,以优化应用启动速度和内存占用。它是 Android 系统启动后第一个由 init 进程启动的 Java 进程,后续所有 Android 应用进程(如 system_server 和用户应用)都由它 fork 而来。Zygote主要有以下几种作用。

  • 预加载 Java 类和资源
    在启动时加载 Android 核心类(如 Activity、View、Context)和系统资源(如 framework-res.apk),避免每个应用重复加载,节省内存和时间。

  • 进程孵化(fork)
    当启动新应用时,Zygote 会 fork 自身,生成一个新的子进程(即应用进程),并继承已预加载的类,减少启动开销。

  • 安全管理
    继承 Zygote 的安全策略(如 SELinux 上下文、UID/GID),确保应用运行在正确的权限环境下。

搜寻Zygote源码位置

我们在Android 12系统源码_系统启动(一)init进程这篇文章中有提到过init.rc脚本。

system/core/rootdir/init.rc

import /init.environ.rc
import /system/etc/init/hw/init.usb.rc
import /init.${ro.hardware}.rc
import /vendor/etc/init/hw/init.${ro.hardware}.rc
import /system/etc/init/hw/init.usb.configfs.rc
import /system/etc/init/hw/init.${ro.zygote}.rc

实际运行中的系统中,/system/etc/init/hw目录的具体内容如下所示:

# 进入/system/etc/init/hw目录,输入ls指令
# 可以看到如下内容init.rc  init.usb.configfs.rc  init.usb.rc  init.zygote32.rc  init.zygote64_32.rc

由于我本地的系统getprop ro.zygote的值是zygote64_32,这样init.rc引用的自然就是init.zygote64_32.rc脚本文件,Android系统/system/etc/init/hw/目录中的.rc脚本,最初都是从源码system/core/rootdir目录拷贝而来的。
rootdir目录

service zygote /system/bin/app_process64 -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 wificondtask_profiles ProcessCapacityHigh MaxPerformancecritical window=${zygote.critical_window.minute:-off} target=zygote-fatal

结合以上代码可以知道init启动了zygote服务,对应的就是/system/bin/app_process64这个程序。
在aosp源码中通过以下指令进行搜索

grep "app_process" -rn ./ --include="*.bp"

通过以上指令我们可以定位到如下内容
搜索结果
可以知道app_process程序对应的源码地址为frameworks/base/cmds/app_process

Zygote入口函数

frameworks/base/cmds/app_process/app_main.cpp

class AppRuntime : public AndroidRuntime
{
public:AppRuntime(char* argBlockStart, const size_t argBlockLength): AndroidRuntime(argBlockStart, argBlockLength), mClass(NULL){}
}
#if defined(__LP64__)
static const char ABI_LIST_PROPERTY[] = "ro.product.cpu.abilist64";
static const char ZYGOTE_NICE_NAME[] = "zygote64";
#else
static const char ABI_LIST_PROPERTY[] = "ro.product.cpu.abilist32";
static const char ZYGOTE_NICE_NAME[] = "zygote";
#endif
int main(int argc, char* const argv[])
{if (!LOG_NDEBUG) {String8 argv_String;for (int i = 0; i < argc; ++i) {argv_String.append("\"");argv_String.append(argv[i]);argv_String.append("\" ");}ALOGV("app_process main with argv: %s", argv_String.string());}//注释1,进行AppRuntime的构造AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));// 忽略 argv[0](程序名)argc--;argv++;const char* spaced_commands[] = { "-cp", "-classpath" };bool known_command = false;int i;for (i = 0; i < argc; i++) {if (known_command == true) {runtime.addOption(strdup(argv[i]));ALOGV("app_process main add known option '%s'", argv[i]);known_command = false;continue;}for (int j = 0;j < static_cast<int>(sizeof(spaced_commands) / sizeof(spaced_commands[0]));++j) {if (strcmp(argv[i], spaced_commands[j]) == 0) {known_command = true;ALOGV("app_process main found known command '%s'", argv[i]);}}if (argv[i][0] != '-') {break;}if (argv[i][1] == '-' && argv[i][2] == 0) {++i; // Skip --.break;}runtime.addOption(strdup(argv[i]));ALOGV("app_process main add option '%s'", argv[i]);}bool zygote = false;bool startSystemServer = false;bool application = false;String8 niceName;String8 className;++i;//跳过 "parent dir" 参数  //解析启动模式while (i < argc) {const char* arg = argv[i++];if (strcmp(arg, "--zygote") == 0) {zygote = true;niceName = ZYGOTE_NICE_NAME;// "zygote" 或 "zygote64"} else if (strcmp(arg, "--start-system-server") == 0) {startSystemServer = true; // 启动 system_server} else if (strcmp(arg, "--application") == 0) {application = true;// 标记为普通应用} else if (strncmp(arg, "--nice-name=", 12) == 0) {niceName.setTo(arg + 12);// 设置进程名(如 "webview_zygote")} else if (strncmp(arg, "--", 2) != 0) {className.setTo(arg);break;} else {--i;break;}}//准备启动参数Vector<String8> args;if (!className.isEmpty()) {// 普通 Java 模式args.add(application ? String8("application") : String8("tool"));runtime.setClassNameAndArgs(className, argc - i, argv + i);if (!LOG_NDEBUG) {String8 restOfArgs;char* const* argv_new = argv + i;int argc_new = argc - i;for (int k = 0; k < argc_new; ++k) {restOfArgs.append("\"");restOfArgs.append(argv_new[k]);restOfArgs.append("\" ");}ALOGV("Class name = %s, args = %s", className.string(), restOfArgs.string());}} else {// Zygote 模式maybeCreateDalvikCache();// 确保 Dalvik 缓存目录存在if (startSystemServer) {args.add(String8("start-system-server"));// 告知 Zygote 启动 system_server}char prop[PROP_VALUE_MAX];if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) {LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.",ABI_LIST_PROPERTY);return 11;}String8 abiFlag("--abi-list=");abiFlag.append(prop);args.add(abiFlag);// 添加剩余参数for (; i < argc; ++i) {args.add(String8(argv[i]));}}if (!niceName.isEmpty()) {// 设置进程名(如 "zygote")runtime.setArgv0(niceName.string(), true /* setProcName */);}if (zygote) {//注释2,启动 JVM,调用ZygoteInit.main(),进入 Zygote 的主循环。runtime.start("com.android.internal.os.ZygoteInit", args, zygote);} else if (className) {//启动 JVM,调用 RuntimeInit.main(),直接运行指定的 Java 类。runtime.start("com.android.internal.os.RuntimeInit", args, zygote);} else {fprintf(stderr, "Error: no class name or --zygote supplied.\n");app_usage();LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");}
}

在注释1处,进行AppRuntime的构造,该类继承自AndroidRuntime。
由于我们这里主要是分析zgote主线逻辑,继续关注注释2处,调用runtime的start方法。

AndroidRuntime的start方法

frameworks/base/core/jni/AndroidRuntime.cpp

void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{//日志打印 AndroidRuntime: >>>>>> START com.android.internal.os.ZygoteInitALOGD(">>>>>> START %s uid %d <<<<<<\n",className != NULL ? className : "(unknown)", getuid());static const String8 startSystemServer("start-system-server");// Whether this is the primary zygote, meaning the zygote which will fork system server.bool primary_zygote = false;...代码省略...JniInvocation jni_invocation;jni_invocation.Init(NULL);JNIEnv* env;//启动java需要的jvm环境,才可以运行java代码if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {return;}onVmCreated(env);/** Register android functions.*/if (startReg(env) < 0) {ALOGE("Unable to register all android natives\n");return;}jclass stringClass;jobjectArray strArray;jstring classNameStr;stringClass = env->FindClass("java/lang/String");assert(stringClass != NULL);strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);assert(strArray != NULL);classNameStr = env->NewStringUTF(className);assert(classNameStr != NULL);env->SetObjectArrayElement(strArray, 0, classNameStr);for (size_t i = 0; i < options.size(); ++i) {jstring optionsStr = env->NewStringUTF(options.itemAt(i).string());assert(optionsStr != NULL);env->SetObjectArrayElement(strArray, i + 1, optionsStr);}char* slashClassName = toSlashClassName(className != NULL ? className : "");jclass startClass = env->FindClass(slashClassName);if (startClass == NULL) {ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);} else {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方法//startClass = com.android.internal.os.ZygoteInit//startMeth = main//strArray 字符串集合,存放方法参数env->CallStaticVoidMethod(startClass, startMeth, strArray);}}...代码省略...
}

app_main主要做的工作就是准备虚拟机环境,让进程运行到了java世界的ZygoteInit的main方法

ZygoteInit的main方法

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

public class ZygoteInit {public static void main(String[] argv) {ZygoteServer zygoteServer = null;//禁止在 Zygote 中创建线程,确保调用fork()方法构建子进程时进程状态简单。ZygoteHooks.startZygoteNoThreadCreation();try {//将 Zygote 设为独立的进程组,避免被信号误杀。Os.setpgid(0, 0);} catch (ErrnoException ex) {throw new RuntimeException("Failed to setpgid(0,0)", ex);}Runnable caller;try {// 记录启动时间(用于性能统计)final long startTime = SystemClock.elapsedRealtime();final boolean isRuntimeRestarted = "1".equals(SystemProperties.get("sys.boot_completed"));// 初始化 Trace 和日志工具(区分 32/64 位 Zygote)String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";// 用于记录启动耗时TimingsTraceLog bootTimingsTraceLog = new TimingsTraceLog(bootTimeTag,Trace.TRACE_TAG_DALVIK);bootTimingsTraceLog.traceBegin("ZygoteInit");RuntimeInit.preForkInit();// 初始化运行时环境boolean startSystemServer = false;String zygoteSocketName = "zygote";String abiList = null;boolean enableLazyPreload = false;for (int i = 1; i < argv.length; i++) {if ("start-system-server".equals(argv[i])) {//是否启动 system_serverstartSystemServer = true;} else if ("--enable-lazy-preload".equals(argv[i])) {//是否延迟预加载(优化启动速度)enableLazyPreload = true;} else if (argv[i].startsWith(ABI_LIST_ARG)) {// 支持的 CPU ABI 列表abiList = argv[i].substring(ABI_LIST_ARG.length());} else if (argv[i].startsWith(SOCKET_NAME_ARG)) {// "--socket-name="zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length());} else {throw new RuntimeException("Unknown command line argument: " + argv[i]);}}final boolean isPrimaryZygote = zygoteSocketName.equals(Zygote.PRIMARY_SOCKET_NAME);if (!isRuntimeRestarted) {if (isPrimaryZygote) {FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__ZYGOTE_INIT_START,startTime);} else if (zygoteSocketName.equals(Zygote.SECONDARY_SOCKET_NAME)) {FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__SECONDARY_ZYGOTE_INIT_START,startTime);}}if (abiList == null) {throw new RuntimeException("No ABI list supplied.");}if (!enableLazyPreload) {bootTimingsTraceLog.traceBegin("ZygotePreload");EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,SystemClock.uptimeMillis());preload(bootTimingsTraceLog);// 注释1,预加载类、资源、OpenGL等EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,SystemClock.uptimeMillis());bootTimingsTraceLog.traceEnd();// ZygotePreload}// Do an initial gc to clean up after startupbootTimingsTraceLog.traceBegin("PostZygoteInitGC");gcAndFinalize();// 触发 GC 清理预加载后的内存bootTimingsTraceLog.traceEnd();// PostZygoteInitGCbootTimingsTraceLog.traceEnd();// ZygoteInitZygote.initNativeState(isPrimaryZygote);// 初始化 Native 层状态ZygoteHooks.stopZygoteNoThreadCreation();//解除线程创建限制,允许后续操作创建线程。zygoteServer = new ZygoteServer(isPrimaryZygote);//构造方法中会创建Zygote端需要的socketif (startSystemServer) {// 注释1,fork出system_server子进程Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);//如果是父进程则返回null,如果是system_server子进程则返回SystemServerRunnableif (r != null) {r.run();return;}}Log.i(TAG, "Accepting command socket connections");//注释3,阻塞监听Socket,这轮询会在zygote进程中无限循环,但是如果fork出子进程(system_server或者Android应用进程)就会退出来caller = zygoteServer.runSelectLoop(abiList);} catch (Throwable ex) {Log.e(TAG, "System zygote died with fatal exception", ex);throw ex;} finally {if (zygoteServer != null) {//system_server进程和android应用进程会关闭socket,zygote仍然在runSelectLoop中轮询监听socketzygoteServer.closeServerSocket();}}if (caller != null) {caller.run(); // 注释4,在子进程中执行(如启动 ActivityThread)}}
}

在注释1处调用preload方法进行预加载。
在注释2处调用 Zygote.forkSystemServer() 创建system_server子进程,如果是父进程则返回null,如果是子进程则返回SystemServer的Runnable对象,并进一步调用该Runnable对象的run方法,最终会进入SystemServer的main方法中,加载Android系统需要的各种服务。
在注释3处调用zygoteServer的runSelectLoop方法阻塞监听Socket,等待 AMS 发送 fork 请求,收到请求后创建对应的子进程。
以上就是ZygoteInit的main方法的主要代码,下面我们具体分析一下。
在注释4处,如果当前是子进程,其实就是应用进程,则调用其返回的Runnable的run方法,最终会进入ActivityThread的main方法。

预加载

注释1处调用preload方法,预加载以下内容。

    static void preload(TimingsTraceLog bootTimingsTraceLog) {Log.d(TAG, "begin preload");...代码省略...beginPreload();...代码省略...preloadClasses();//加载/system/etc/preloaded-classes目录下的类。...代码省略...preloadResources();//加载系统资源/system/framework/framework-res.apk...代码省略...preloadSharedLibraries();preloadTextResources();...代码省略...Log.d(TAG, "end preload");sPreloadComplete = true;}

孵化子进程,返回Runnable对象

在注释2处调用 Zygote.forkSystemServer() 孵化system_server子进程,如果是父进程则返回null,如果是子进程则返回实现了Runnable接口的MethodAndArgsCaller对象,并进一步调用该Runnable对象的run方法,最终会进入SystemServer的main方法中,加载Android系统需要的各种服务。

孵化system_server子进程

public class ZygoteInit {private static Runnable forkSystemServer(String abiList, String socketName,ZygoteServer zygoteServer) {...代码省略.../* Hardcoded command line to start the system server */String[] args = {"--setuid=1000",//用户id"--setgid=1000",//组id"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,"+ "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010,3011,3012","--capabilities=" + capabilities + "," + capabilities,"--nice-name=system_server","--runtime-args","--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,"com.android.server.SystemServer",//SystemServer类名,只有这个条目是非--开头的};ZygoteArguments parsedArgs;int pid;try {...代码省略...parsedArgs = ZygoteArguments.getInstance(commandBuffer);...代码省略.../*调用Zygote的forkSystenServer方法fork system_server进程*/pid = Zygote.forkSystemServer(parsedArgs.mUid, parsedArgs.mGid,parsedArgs.mGids,parsedArgs.mRuntimeFlags,null,parsedArgs.mPermittedCapabilities,parsedArgs.mEffectiveCapabilities);} catch (IllegalArgumentException ex) {throw new RuntimeException(ex);}if (pid == 0) {...代码省略...//由于zygoteServer只有Zygote会使用,子进程system_server不需要使用,于是会将其关闭。zygoteServer.closeServerSocket();//继续调用handleSystemServerProcess方法return handleSystemServerProcess(parsedArgs);}return null;}
}   
>frameworks/base/core/java/com/android/internal/os/Zygote.javapublic final class Zygote {static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {...代码省略...int pid = nativeForkSystemServer(uid, gid, gids, runtimeFlags, rlimits,permittedCapabilities, effectiveCapabilities);...代码省略...return pid;}   private static native int nativeForkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);     }

开启线程池,返回实现了Runnable接口的MethodAndArgsCaller对象

public class ZygoteInit {private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {...代码省略...//从环境变量SYSTEMSERVERCLASSPATH获取到SystemServer类文件相应jar包的路径final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");if (systemServerClasspath != null) {//对相应的jar包做dex优化处理performSystemServerDexOpt(systemServerClasspath);...代码省略...}...代码省略...ClassLoader cl = getOrCreateSystemServerClassLoader();//创建类加载器if (cl != null) {Thread.currentThread().setContextClassLoader(cl);}//调用ZygoteInit的zygoteInit方法return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,parsedArgs.mDisabledCompatChanges,parsedArgs.mRemainingArgs, cl);}public static Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,String[] argv, ClassLoader classLoader) {...代码省略...RuntimeInit.redirectLogStreams();RuntimeInit.commonInit();//调用native方法,主要是开启ProcessState线程池,用来进行binder通信ZygoteInit.nativeZygoteInit();//调用RuntimeInit的applicationInit方法return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,classLoader);}private static native void nativeZygoteInit();  }>frameworks/base/core/jni/AndroidRuntime.cppint register_com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env)
{const JNINativeMethod methods[] = {{ "nativeZygoteInit", "()V",(void*) com_android_internal_os_ZygoteInit_nativeZygoteInit },};return jniRegisterNativeMethods(env, "com/android/internal/os/ZygoteInit",methods, NELEM(methods));
}
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{gCurRuntime->onZygoteInit();
}>frameworks/base/cmds/app_process/app_main.cppvirtual void onZygoteInit(){sp<ProcessState> proc = ProcessState::self();ALOGV("App process: starting thread pool.\n");proc->startThreadPool();//开启线程池}>frameworks/base/core/java/com/android/internal/os/RuntimeInit.javapublic class RuntimeInit {protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,String[] argv, ClassLoader classLoader) {...代码省略...final Arguments args = new Arguments(argv);//解析参数argvreturn findStaticMain(args.startClass, args.startArgs, classLoader);}static class Arguments {String startClass;//类路径String[] startArgs;//参数Arguments(String args[]) throws IllegalArgumentException {parseArgs(args);}private void parseArgs(String args[])throws IllegalArgumentException {int curArg = 0;for (; curArg < args.length; curArg++) {String arg = args[curArg];if (arg.equals("--")) {curArg++;break;} else if (!arg.startsWith("--")) {//com.android.server.SystemServer字符串break;}}if (curArg == args.length) {throw new IllegalArgumentException("Missing classname argument to RuntimeInit!");}startClass = args[curArg++];startArgs = new String[args.length - curArg];System.arraycopy(args, curArg, startArgs, 0, startArgs.length);}        }    protected static Runnable findStaticMain(String className, String[] argv, ClassLoader classLoader) {Class<?> cl;...代码省略..//获取到SystemServer的类字节cl = Class.forName(className, true, classLoader);...代码省略..Method m;//获取到main方法的方法idm = cl.getMethod("main", new Class[] { String[].class });...代码省略..//这个就是ZygoteInit类中forkSystemServer的返回值rreturn new MethodAndArgsCaller(m, argv);}static class MethodAndArgsCaller implements Runnable {private final Method mMethod;private final String[] mArgs;public MethodAndArgsCaller(Method method, String[] args) {mMethod = method;mArgs = args;}public void run() {...代码省略...//通过反射调用mMethod静态方法,这里触发的其实就是SystemServer的main方法mMethod.invoke(null, new Object[] { mArgs });...代码省略...}}}

监听socket,等待AMS发送fork请求

注释3处调用zygoteServer的runSelectLoop方法阻塞监听Socket,等待 AMS 发送 fork 请求,收到请求后创建对应的子进程。

frameworks/base/core/java/com/android/internal/os/ZygoteServer.java

class ZygoteServer {private LocalServerSocket mZygoteSocket;//服务端socketZygoteServer(boolean isPrimaryZygote) {...代码省略...//调用Zygote的createManagedSocketFromInitSocket方法创建Zygote端需要的socketmZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.PRIMARY_SOCKET_NAME);...代码省略...       }/*** 开启zygote进程轮询监听。接收新的socket连接(会创建新的ZygoteConnection)* 并且从这些链接中中读取命令,并且执行*/Runnable runSelectLoop(String abiList) {ArrayList<FileDescriptor> socketFDs = new ArrayList<>();ArrayList<ZygoteConnection> peers = new ArrayList<>();socketFDs.add(mZygoteSocket.getFileDescriptor());peers.add(null);...代码省略...int pollReturnValue;try {//开启轮询pollReturnValue = Os.poll(pollFDs, pollTimeoutMs);} catch (ErrnoException ex) {throw new RuntimeException("poll failed", ex);}if (pollReturnValue == 0) {mUsapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP;mUsapPoolRefillAction = UsapPoolRefillAction.DELAYED;} else {boolean usapPoolFDRead = false;while (--pollIndex >= 0) {if ((pollFDs[pollIndex].revents & POLLIN) == 0) {continue;}if (pollIndex == 0) {//如果是新的socket链接请求(建立新连接)//新建ZygoteConnection链接ZygoteConnection newPeer = acceptCommandPeer(abiList);//添加到链接数组中peers.add(newPeer);//添加到文件描述符数组中socketFDs.add(newPeer.getFileDescriptor());} else if (pollIndex < usapPoolEventFDIndex) {//如果是之前已经建立的socket链接(在已有连接上)try {//获取对应的ZygoteConnectionZygoteConnection connection = peers.get(pollIndex);boolean multipleForksOK = !isUsapPoolEnabled()&& ZygoteHooks.isIndefiniteThreadSuspensionSafe();//会执行ZygoteConnection发送过来的命令final Runnable command = connection.processCommand(this, multipleForksOK);if (mIsForkChild) {//子进程...代码省略...//退出,command就是前面的ZygoteInit的caller对象return command;} else {//父进程,上面是while无限循环,zygote进程永远不会退出...代码省略...if (connection.isClosedByPeer()) {connection.closeSocket();peers.remove(pollIndex);socketFDs.remove(pollIndex);}}} catch (Exception e) {...代码省略...} finally {mIsForkChild = false;}}}}}
}
>frameworks/base/core/java/com/android/internal/os/Zygote.java
public final class Zygote {public static final String PRIMARY_SOCKET_NAME = "zygote";private static final String ANDROID_SOCKET_PREFIX = "ANDROID_SOCKET_";static LocalServerSocket createManagedSocketFromInitSocket(String socketName) {int fileDesc;//fullSocketName为“ANDROID_SOCKET_zygote”final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;try {//获取ANDROID_SOCKET_zygote的坏境变量(即为/dev/socket/zygote的文件描述符的值)//该变量是init进程在启动zygote进程时保存到环境变量中的String env = System.getenv(fullSocketName);fileDesc = Integer.parseInt(env);} catch (RuntimeException ex) {throw new RuntimeException("Socket unset or invalid: " + fullSocketName, ex);}try {//绑定socket,在后面用来接收Android应用启动请求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);}}
}

fork应用进程,进入ActivityThread的Main方法

ZygoteConnection的processCommand方法如下所示。

class ZygoteConnection {Runnable processCommand(ZygoteServer zygoteServer, boolean multipleOK) {...代码省略...//fork子进程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.mAllowlistedDataInfoList, parsedArgs.mBindMountAppDataDirs,parsedArgs.mBindMountAppStorageDirs);try {if (pid == 0) {//当前进程是子进程中(应用进程中)zygoteServer.setForkChild();zygoteServer.closeServerSocket();IoUtils.closeQuietly(serverPipeFd);serverPipeFd = null;//继续调用handleChildProc方法return handleChildProc(parsedArgs, childPipeFd,parsedArgs.mStartChildZygote);} else {//当前进程是父进程中(zygote)return null;}} ...代码省略...}private Runnable handleChildProc(ZygoteArguments parsedArgs,FileDescriptor pipeFd, boolean isZygote) {//关闭ZygoteConnection中的socket链接closeSocket();Zygote.setAppProcessName(parsedArgs, TAG);...代码省略...if (!isZygote) {//执行ZygoteInit的zygoteInit方法,这里返回的是ActivityThread的main方法的Runnablereturn ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,parsedArgs.mDisabledCompatChanges,parsedArgs.mRemainingArgs, null /* classLoader */);} else {return ZygoteInit.childZygoteInit(parsedArgs.mRemainingArgs  /* classLoader */);}}
}

如果当前进程是应用子进程,则会返回的是ActivityThread的main方法,最终会进入ActivityThread的main方法中。

时序图

从Zygote进程所在的Native层 -> ZygoteInit所在的JVM层 -> SystemServer进程的启动
时序图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/41848.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

精华贴分享|从不同的交易理论来理解头肩形态,殊途同归

本文来源于量化小论坛策略分享会板块精华帖&#xff0c;作者为孙小迪&#xff0c;发布于2025年2月17日。 以下为精华帖正文&#xff1a; 01 前言 学习了一段时间交易后&#xff0c;我发现在几百年的历史中&#xff0c;不同门派的交易理论对同一种市场特征的称呼不一样&#x…

C++智能指针万字详细讲解(包含智能指针的模拟实现)

在笔试&#xff0c;面试中智能指针经常出现&#xff0c;如果你对智能指针的作用&#xff0c;原理&#xff0c;用法不了解&#xff0c;那么可以看看这篇博客讲解&#xff0c;此外本博客还简单模拟实现了各种指针&#xff0c;在本篇的最后还应对面试题对智能指针的知识点进行了拓…

学习threejs,使用多面体(IcosahedronGeometry、TetrahedronGeometry、OctahedronGeometry等)

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.PolyhedronGeometry …

DeepSeek详解:探索下一代语言模型

文章目录 前言一、什么是DeepSeek二、DeepSeek核心技术2.1 Transformer架构2.1.1 自注意力机制 (Self-Attention Mechanism)(a) 核心思想(b) 计算过程(c) 代码实现 2.1.2 多头注意力 (Multi-Head Attention)(a) 核心思想(b) 工作原理(c) 数学描述(d) 代码实现 2.1.3 位置编码 (…

【目标检测】【深度学习】【Pytorch版本】YOLOV1模型算法详解

【目标检测】【深度学习】【Pytorch版本】YOLOV1模型算法详解 文章目录 【目标检测】【深度学习】【Pytorch版本】YOLOV1模型算法详解前言YOLOV1的模型结构YOLOV1模型的基本执行流程YOLOV1模型的网络参数YOLOV1模型的训练方式 YOLOV1的核心思想前向传播阶段网格单元(grid cell)…

网络运维学习笔记(DeepSeek优化版) 022 HCIP-Datacom路由概念、BFD协议详解与OSPF第一课

文章目录 路由概念、BFD协议详解与OSPF第一课一、路由协议优先级与选路原则1.1 路由协议优先级对照表1.2 路由选路核心原则 二、BFD&#xff08;Bidirectional Forwarding Detection&#xff0c;双向转发检测&#xff09;的配置与应用2.1 双向心跳探测&#xff08;双端配置&…

单应性矩阵(homography)

利用单应性矩阵计算内外参矩阵 利用单应性矩阵解决问题 问题描述&#xff1a;

Scavenge算法的优缺点问题

Scavenge 的缺点是只能使用堆内存中的一半&#xff0c;这是由划分空间和复制机制所决定的。但 Scavenge 由于只复制存活的对象&#xff0c;并且对于生命周期短的场景&#xff0c;存活对象只占少部分&#xff0c;所以它在时间效率上有优异的表现。 由于 Scavenge 是典型的牺牲空…

丝杆支撑座间隙调整不当会带来哪些影响?

丝杆支撑座是一种用于支撑滚珠丝杆的零件&#xff0c;通常用于机床、数控机床、自动化生产线等高精度机械设备中。支撑座间隙调整不当会对机械设备的运行产生多方面的影响&#xff0c;接下来一起了解一下&#xff1a; 1、降低加工精度&#xff1a;在机械加工设备中&#xff0c;…

Unity:EasyRoad3D插件学习 二期

前言&#xff1a; 书接上回。 一、场景视图状态&#xff1a; 创建好道路以后&#xff0c;切换到第一个选项&#xff0c;场景视图状态&#xff0c;查看道路信息&#xff0c;Main Settings修改道路名称、类型&#xff0c;宽度&#xff0c;是否闭环。 RoadWidth改为15&#xff…

内网渗透-DLL和C语言加载木马

免杀进阶技术 1、DLL的定义与使用 DLL:Dynamic Link library,动态链接库&#xff0c;是一个无法自己运行&#xff0c;需要额外的命令或程序来对其接口进行调用&#xff08;类方法、函数&#xff09;。 (1)在DevCpp中创建一个DLL项目 (2)在dllmain.c中定义源代码函数接口 #i…

一洽让常见问题的快速咨询,触手可及

在客户服务场景中&#xff0c;重复性常见问题的处理效率直接影响用户体验与客服成本。针对重复性常见问题&#xff0c;如何以直观的方式呈现给用户&#xff0c;使其能够快速、精准地提出咨询&#xff0c;已成为提升客户满意度的关键因素。 一、传统客服模式的效率枷锁 用户咨…

WEB攻防-Java安全SPEL表达式SSTI模版注入XXEJDBCMyBatis注入

目录 靶场搭建 JavaSec ​编辑​编辑 Hello-Java-Sec(可看到代码对比) SQL注入-JDBC(Java语言连接数据库) 1、采用Statement方法拼接SQL语句 2.PrepareStatement会对SQL语句进行预编译&#xff0c;但如果直接采取拼接的方式构造SQL&#xff0c;此时进行预编译也无用。 3、…

树莓集团南京园区启航:数字经济新地标!

深耕数字产业&#xff0c;构筑生态闭环 树莓集团在数字产业领域拥有超过十年的深厚积累&#xff0c;专注于构建“数字产业”的融合生态链。其核心优势在于有效整合政府、产业、企业及高校资源&#xff0c;形成一个协同创新、价值共生的产业生态闭环系统。 赋能转型&#xff0c…

Redis之bimap/hyperloglog/GEO

bimap/hyperloglog/GEO的真实需求 这些需求的痛点&#xff1a;亿级数据的收集清洗统计展现。一句话&#xff1a;存的进取得快多维度 真正有价值的是统计。 统计的类型 亿级系统中常见的四种统计 聚合统计 统计多个集合元素的聚合结果&#xff0c;就是交差并等集合统计。 排…

nara wpe去混响学习笔记

文章目录 1.WPE方法去混响的基本流程1.1.基本流程 2.离线迭代方法3.在线求法3.1.回顾卡尔曼方法3.2.在线去混响递推滤波器G方法 nara wpe git地址 博客中demo代码下载 参考论文 NARA - WPE: A Python Package for Weighted Prediction Error Dereverberation in Numpy and Ten…

JavaScript函数、箭头函数、匿名函数

1.示例代码(包括用法和注意事项) <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>JS-函数</title…

练习:求平方根

需求&#xff1a;键盘录入一个大于等于2的整数x&#xff0c;计算并返回x的平方根。结果只保留整数部分&#xff0c;小数部分将被舍去。 代码一&#xff1a; //求平方根 //方法一&#xff1a; package Online; import java.util.Scanner; public class SquareRoot {public sta…

win10 安装后的 系统盘的 分区

win10 安装后的 系统盘的 分区 MBR 分区 GPT 分区

反向 SSH 隧道技术实现内网穿透

反向 SSH 隧道技术实现内网穿透 场景描述 有一台内网的 Linux PC 机&#xff0c;想在其他地方&#xff08;如家中&#xff09;使用浏览器&#xff0c;在浏览器中能够使用内网 Linux PC 机的命令行。 实现思路 内网 Linux PC 机在内网可以使用 SSH 进行连接&#xff0c;但内…