添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

注意(WARNING):本文含有大量AOSP源码,阅读过程中如出现头晕、目眩、恶心、犯困等症状属正常情况,作者本人亦无法避免症状产生,故不承担任何法律责任。

本文所贴源码全部来自 Android API 29 Platform,即 Android 10.0。

阅读本文需要有一定的C/C++基础。

要想启动一个应用程序,首先要保证这个应用程序所需要的应用程序进程已经启动。

在上两篇文章中我们分别讨论了系统关键进程的启动和Activity的启动流程,已经清楚了两个事实:

  • 应用程序进程由Zygote通过fork自身来创建。
  • Activity启动时将会优先检查应用程序对应进程是否已经存在并且正在运行。
  • 也就是说整个过程至少有SystemServer、Zygote和目标App进程三个进程参与。

    下面将会分为三个部分来介绍,分别是 AMS发送创建App进程请求 Zygote接收请求并创建App进程 App进程初始化

    AMS发送创建App进程请求

    上篇文章 中,ActivityStackSupervisor在执行startSpecificActivityLocked方法时,将会检查App进程是否正在执行,我们从这里继续。

    ActivityStackSupervisor#startSpecificActivityLocked

    frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
    // 通过ATMS获取目标进程的WindowProcessController对象
    // WindowProcessController用于ActivityManager与WindowManager同步进程状态
    // 如果wpc为空,则表示对应进程不存在或者未启动
    final WindowProcessController wpc =
    mService.getProcessController(r.processName, r.info.applicationInfo.uid);

    try {
    ···
    // 如果对应App进程还未启动
    // 通过handler发送消息启动进程
    final Message msg = PooledLambda.obtainMessage(
    ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
    r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
    mService.mH.sendMessage(msg);
    } finally {
    Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }
    }

    此处的mService为ActivityTaskManagerService对象,调用它的getProcessController返回一个WindowProcessController对象,当目标进程未启动时为null。

    如果wpc为null,那么就会使用PooledLambda#obtainMessage来获得一个Message,使用主线程Handler将这条消息发送到主线程中。

    PooledLambda这个类采用了池化技术,用于构造可回收复用的匿名函数。其acquire函数将会尝试在对象池中

    会Kotlin的同学对于双冒号获取函数引用的语法比较熟悉,在Java中这个特性是在JDK 1.8才出现,ActivityManagerInternal::startProcess这行代码实际上返回的是一个Comsumer对象。

    PooledLambda#obtainMessage的源码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    /**
    * 参数解释:
    * function:需要封装的方法引用,为Consumer类型
    * arg1:执行此方法的对象,这里为ActivityManagerService$LocalService对象
    * arg2-6:方法执行所需参数
    */
    static <A, B, C, D, E, F> Message obtainMessage(
    HexConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F> function,
    A arg1, B arg2, C arg3, D arg4, E arg5, F arg6) {
    synchronized (Message.sPoolSync) {
    PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
    function, 6, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, null, null,
    null);
    return Message.obtain().setCallback(callback.recycleOnUse());
    }
    }

    这段代码实际上就是把ActivityManagerInternal#startProcess方法封装成Callback然后设置到Message中。

    由于Handler的callback不为空,那么在分发消息时将会直接执行此Callback,在此例中将会执行PooledLambdaImpl#run方法,继而执行到HexConsumer#invoke方法,从而执行了我们传递过去的方法引用。

    下面我们继续分析ActivityManagerInternal#startProcess方法。

    ActivityManagerInternal#startProcess

    ActivityManagerInternal类是一个抽象类,startProcess也是一个抽象方法,实际由其子类ActivityManagerService$LocalService来实现。

    LocalService是ActivityManagerService的一个内部类,来看看其startProcess方法:

    frameworks/base/services/core/java/com/android/server/am/ActivityManagerService$LocalService.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    @Override
    public void startProcess(String processName, ApplicationInfo info,
    boolean knownToBeDead, String hostingType, ComponentName hostingName) {
    try {
    synchronized (ActivityManagerService.this) {
    startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
    new HostingRecord(hostingType, hostingName),
    false /* allowWhileBooting */, false /* isolated */,
    true /* keepIfLarge */);
    }
    } finally {
    ...
    }
    }

    方法中主要是对后续操作加锁,并将hostingType和hostingName封装到HostingRecord对象中。

    HostingRecord类用于描述进程的启动信息,这里的hostingType可以是activity、service、broadcast、content provider,这里为“activity”,hostingName是对应的组件名ComponentName。

    接着调用了ActivityManagerService中的startProcessLocked方法。

    ActivityManagerService#startProcessLocked

    frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    final ProcessRecord startProcessLocked(String processName,
    ApplicationInfo info, boolean knownToBeDead, int intentFlags,
    HostingRecord hostingRecord, boolean allowWhileBooting,
    boolean isolated, boolean keepIfLarge) {
    return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
    hostingRecord, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
    null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
    null /* crashHandler */);
    }

    将启动进程任务转发给了mProcessList,mProcessList是一个ProcessList对象:

    1
    2
    3
    4
    /**
    * Process management.
    */
    final ProcessList mProcessList = new ProcessList();

    ProcessList是ActivityManager中用于管理进程的类,这个类对于我们理解Android的 进程优先级ADJ算法 有着重要作用,而理解ADJ可以帮助我们提升应用的存活时间( 耍流氓 ),这部分将会在后面单独出文章讨论。

    下面继续跟踪App进程启动。

    ProcessList#startProcessLocked

    frameworks/base/services/core/java/com/android/server/am/ProcessList.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    @GuardedBy("mService")
    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
    boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
    boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
    String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
    long startTime = SystemClock.elapsedRealtime();
    ProcessRecord app;
    // 如果进程是孤立进程
    // 此次流程isolated为false
    if (!isolated) {
    // 通过进程名和uid获取对应ProcessRecord对象
    app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
    // 如果请求来自后台进程
    if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
    // 目标进程是否是一个“坏进程”
    // 坏进程是指短时间内连续崩溃两次以上的进程
    // 坏进程从后台启动进程将会直接失败
    if (mService.mAppErrors.isBadProcessLocked(info)) {
    return null;
    }
    } else {
    // 如果请求不是来自后台进程,那么就来自用户了
    // 这时候需要清除目标进程的崩溃计数,让它成为一个“好进程”
    mService.mAppErrors.resetProcessCrashTimeLocked(info);
    if (mService.mAppErrors.isBadProcessLocked(info)) {
    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
    UserHandle.getUserId(info.uid), info.uid,
    info.processName);
    mService.mAppErrors.clearBadProcessLocked(info);
    if (app != null) {
    app.bad = false;
    }
    }
    }
    } else {
    // 对于孤立进程,无法再利用已存在的进程
    app = null;
    }

    // 如果满足三种条件时,我们可以复用这个进程:
    // 1、已经存在了对应的ProcessRecord对象,并且pid大于0
    // 2、AMS认为它没有死亡,并且进程没有被杀掉
    // 3、或者进程还没有绑定binder线程(IApplicationThread)
    if (app != null && app.pid > 0) {
    if ((!knownToBeDead && !app.killed) || app.thread == null) {
    app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
    return app;
    }

    // 不满足上面的三种条件,说明ProgressRecord绑定在之前的进程,杀死并清理这个进程
    ProcessList.killProcessGroup(app.uid, app.pid);
    mService.handleAppDiedLocked(app, true, true);
    }

    // 如果app为null,说明目标App进程一定不在运行
    // 新建进程之前先创建好ProgressRecord对象
    if (app == null) {
    app = newProcessRecordLocked(info, processName, isolated, isolatedUid, hostingRecord);
    if (app == null) {
    return null;
    }
    app.crashHandler = crashHandler;
    app.isolatedEntryPoint = entryPoint;
    app.isolatedEntryPointArgs = entryPointArgs;
    } else {
    // 这里对应ProgressRecord绑定在之前的进程的情况
    // 清理之后重新绑定新的包信息
    app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
    }

    // 到这里我们已经确保有了App进程的ProcessRecord对象了
    // 如果系统还没准备好就先添加到等待队列中
    // 当进程为persistent,则isAllowedWhileBooting为true,这次流程为false
    if (!mService.mProcessesReady
    && !mService.isAllowedWhileBooting(info)
    && !allowWhileBooting) {
    if (!mService.mProcessesOnHold.contains(app)) {
    mService.mProcessesOnHold.add(app);
    }
    return app;
    }

    final boolean success = startProcessLocked(app, hostingRecord, abiOverride);
    return success ? app : null;
    }

    此方法主要是处理目标进程对应的ProcessRecord对象,ProcessRecord是AMS中用来保存进程信息的类,类似于我们上篇文章中的ActivityRecord。

    接着又调用了本类中的startProcessLocked方法。

    ProcessList#startProcessLocked

    frameworks/base/services/core/java/com/android/server/am/ProcessList.java

    1
    2
    3
    4
    5
    final boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
    String abiOverride) {
    return startProcessLocked(app, hostingRecord,
    false /* disableHiddenApiChecks */, false /* mountExtStorageFull */, abiOverride);
    }

    此方法主要是配置了默认参数,继续跟进。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
    boolean disableHiddenApiChecks, boolean mountExtStorageFull,
    String abiOverride) {

    ···

    // 从等待启动的队列中移除
    mService.mProcessesOnHold.remove(app);

    // 设置一大堆调试Flag
    ···

    try {
    try {
    final int userId = UserHandle.getUserId(app.uid);
    // 检查当前包是否可启动
    AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
    } catch (RemoteException e) {
    throw e.rethrowAsRuntimeException();
    }

    ···

    // 设置进程的入口类
    final String entryPoint = "android.app.ActivityThread";

    // 启动进程
    return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
    runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
    startTime);
    } catch (RuntimeException e) {
    mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
    false, false, true, false, false, app.userId, "start failure");
    return false;
    }
    }

    此方法源码比较长,这里进行了大量删减,它的主要工作是设置App进程挂载外部空间的模式、设置进程的GID,计算RuntimeFlags等。

    这里有一行关键代码:

    1
    final String entryPoint = "android.app.ActivityThread";

    在这里设置了进程的入口函数所在类文件。继续跟进。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    @GuardedBy("mService")
    boolean startProcessLocked(HostingRecord hostingRecord,
    String entryPoint,
    ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
    String seInfo, String requiredAbi, String instructionSet, String invokeWith,
    long startTime) {
    app.pendingStart = true;
    app.killedByAm = false;
    app.removed = false;
    app.killed = false;
    if (app.startSeq != 0) {
    Slog.wtf(TAG, "startProcessLocked processName:" + app.processName
    + " with non-zero startSeq:" + app.startSeq);
    }
    if (app.pid != 0) {
    Slog.wtf(TAG, "startProcessLocked processName:" + app.processName
    + " with non-zero pid:" + app.pid);
    }
    final long startSeq = app.startSeq = ++mProcStartSeqCounter;
    app.setStartParams(uid, hostingRecord, seInfo, startTime);
    app.setUsingWrapper(invokeWith != null
    || SystemProperties.get("wrap." + app.processName) != null);
    mPendingStarts.put(startSeq, app);

    // AMS设置了异步启动进程
    if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
    mService.mProcStartHandler.post(() -> {
    try {
    final Process.ProcessStartResult startResult = startProcess(app.hostingRecord,
    entryPoint, app, app.startUid, gids, runtimeFlags, mountExternal,
    app.seInfo, requiredAbi, instructionSet, invokeWith, app.startTime);
    synchronized (mService) {
    handleProcessStartedLocked(app, startResult, startSeq);
    }
    } catch (RuntimeException e) {
    synchronized (mService) {
    mPendingStarts.remove(startSeq);
    app.pendingStart = false;
    mService.forceStopPackageLocked(app.info.packageName,
    UserHandle.getAppId(app.uid),
    false, false, true, false, false, app.userId, "start failure");
    }
    }
    });
    return true;
    } else {
    try {
    final Process.ProcessStartResult startResult = startProcess(hostingRecord,
    entryPoint, app,
    uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
    invokeWith, startTime);
    handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
    startSeq, false);
    } catch (RuntimeException e) {
    app.pendingStart = false;
    mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
    false, false, true, false, false, app.userId, "start failure");
    }
    return app.pid > 0;
    }
    }

    这里针对AMS采用同步或者异步的启动方式做了一些工作,最终都会调用startProcess方法。

    ProcessList#startProcess

    frameworks/base/services/core/java/com/android/server/am/ProcessList.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
    ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
    String seInfo, String requiredAbi, String instructionSet, String invokeWith,
    long startTime) {
    try {
    final Process.ProcessStartResult startResult;
    // 是否从webviewZygote创建进程
    // 这种情况下会通过WebViewZygote来启动进程
    if (hostingRecord.usesWebviewZygote()) {
    startResult = startWebView(entryPoint,
    app.processName, uid, uid, gids, runtimeFlags, mountExternal,
    app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
    app.info.dataDir, null, app.info.packageName,
    new String[] {PROC_START_SEQ_IDENT + app.startSeq});
    } else if (hostingRecord.usesAppZygote()) {
    // 是否从AppZygote来创建进程
    final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);

    startResult = appZygote.getProcess().start(entryPoint,
    app.processName, uid, uid, gids, runtimeFlags, mountExternal,
    app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
    app.info.dataDir, null, app.info.packageName,
    /*useUsapPool=*/ false,
    new String[] {PROC_START_SEQ_IDENT + app.startSeq});
    } else {
    // 从默认的Zygote中创建进程
    // 本次流程进入这里
    startResult = Process.start(entryPoint,
    app.processName, uid, uid, gids, runtimeFlags, mountExternal,
    app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
    app.info.dataDir, invokeWith, app.info.packageName,
    new String[] {PROC_START_SEQ_IDENT + app.startSeq});
    }
    return startResult;
    } finally {
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    }
    }

    此方法主要是判断应该由哪个Zygote进程来创建我们的App进程。

    一般情况下,我们不指定Zygote进程时,HostingRecord中使用默认Zygote。

    1
    2
    3
    public HostingRecord(String hostingType, ComponentName hostingName) {
    this(hostingType, hostingName, REGULAR_ZYGOTE);
    }

    Process#start方法把进程的启动工作转发给了ZygoteProcess,ZygoteProcess#start又调用了startViaZygote方法,我们直接来到startViaZygote方法中。

    ZygoteProcess#startViaZygote

    frameworks/base/core/java/android/os/ZygoteProcess.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    private Process.ProcessStartResult startViaZygote(@NonNull final String processClass,
    @Nullable final String niceName,
    final int uid, final int gid,
    @Nullable final int[] gids,
    int runtimeFlags, int mountExternal,
    int targetSdkVersion,
    @Nullable String seInfo,
    @NonNull String abi,
    @Nullable String instructionSet,
    @Nullable String appDataDir,
    @Nullable String invokeWith,
    boolean startChildZygote,
    @Nullable String packageName,
    boolean useUsapPool,
    @Nullable String[] extraArgs)
    throws ZygoteStartFailedEx {
    ArrayList<String> argsForZygote = new ArrayList<>();

    // 设置启动参数
    argsForZygote.add("--runtime-args");
    argsForZygote.add("--setuid=" + uid);
    argsForZygote.add("--setgid=" + gid);
    argsForZygote.add("--runtime-flags=" + runtimeFlags);

    ···

    synchronized(mLock) {
    // 发送参数到Zygote并且获取结果
    return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
    useUsapPool,
    argsForZygote);
    }
    }

    该过程主要工作是生成argsForZygote数组,该数组保存了进程的uid、pid、groups、targetSDK、niceName等一系列参数。

    ZygoteProcess#zygoteSendArgsAndGetResult

    frameworks/base/core/java/android/os/ZygoteProcess.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    private Process.ProcessStartResult zygoteSendArgsAndGetResult(
    ZygoteState zygoteState, boolean useUsapPool, @NonNull ArrayList<String> args)
    throws ZygoteStartFailedEx {
    // 检验参数列表是否合法
    ···

    // 此次流程useUsapPool = true && mUsapPoolEnabled = false
    if (useUsapPool && mUsapPoolEnabled && canAttemptUsap(args)) {
    try {
    return attemptUsapSendArgsAndGetResult(zygoteState, msgStr);
    } catch (IOException ex) {
    // If there was an IOException using the USAP pool we will log the error and
    // attempt to start the process through the Zygote.
    Log.e(LOG_TAG, "IO Exception while communicating with USAP pool - "
    + ex.getMessage());
    }
    }
    // 本次流程走这里
    return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr);
    }

    这里出现了一个新名词: UsapPool 。UsapPool是Android 10中的一种新机制,主要就是在Zygote里面维护一个 进程池 ,不过android 10中并没有开启此功能,也就是mUsapPoolEnabled参数默认时为false的。

    ZygoteProcess#attemptZygoteSendArgsAndGetResult

    frameworks/base/core/java/android/os/ZygoteProcess.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
    ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
    try {
    // zygoteState由openZygoteSocketIfNeeded方法返回
    // openZygoteSocketIfNeeded方法方法根据abi类型选择Zygote还是Zygote64的ZygoteState
    // 获取服务端(Zygote)输出流
    final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
    // // 获取服务端(Zygote)输入流
    final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;

    // 将参数写入Zygote
    zygoteWriter.write(msgStr);
    zygoteWriter.flush();

    Process.ProcessStartResult result = new Process.ProcessStartResult();
    // 获取Zygote返回的结果
    result.pid = zygoteInputStream.readInt();
    result.usingWrapper = zygoteInputStream.readBoolean();

    if (result.pid < 0) {
    throw new ZygoteStartFailedEx("fork() failed");
    }

    return result;
    } catch (IOException ex) {
    zygoteState.close();
    Log.e(LOG_TAG, "IO Exception while communicating with Zygote - "
    + ex.toString());
    throw new ZygoteStartFailedEx(ex);
    }
    }

    这个方法的主要功能是通过socket通道向Zygote进程发送一个参数列表,然后进入阻塞等待状态,直到远端的socket服务端发送回来新创建的进程pid才返回。

    到这里SystemServer所做的前置工作就完成了。

    小结

    我们来回顾一下本节中SystemServer的主要工作。

    SystemServer在启动一个Activity时,会判断Activity对应进程是否存在,不存在则会启动该进程。

    进程启动代码由ActivityManagerService$LocalService开始,接着将会转发到ProcessList中。

    ProcessList会检查进程是否是孤立进程,尝试获取现有的ProcessRecord对象,并且尝试复用进程。

    如果无法复用进程,那么将会继续配置参数启动该进程,其中配置了目标进程的入口类:

    1
    final String entryPoint = "android.app.ActivityThread";

    最终会通过Socket的方式将参数发送到Zygote中,并且阻塞等待返回。

    时序图如下所示。

    Zygote接收请求并创建App进程

    在之前的 系统进程启动过程 一文中我们知道,Zygote在创建完SystemServer后,将会开启无限循环以等待子进程的请求,具体的流程已经在文中分析过了,这里简单过一遍。

    ZygoteServer#runSelectLoop

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    Runnable runSelectLoop(String abiList) {

    ···

    while (--pollIndex >= 0) {
    if ((pollFDs[pollIndex].revents & POLLIN) == 0) {
    continue;
    }

    if (pollIndex == 0) {
    // 收到新的建立通信的请求,建立通信连接
    ZygoteConnection newPeer = acceptCommandPeer(abiList);
    // 加入到peers和fds, 即下一次也开始监听
    peers.add(newPeer);
    socketFDs.add(newPeer.getFileDescriptor());
    } else if (pollIndex < usapPoolEventFDIndex) {
    // 说明接收到AMS发送过来创建应用程序的请求,调用processOneCommand来创建新的应用程序进程
    try {
    //有socket连接,创建ZygoteConnection对象,并添加到fds
    ZygoteConnection connection = peers.get(pollIndex);
    // 处理连接
    final Runnable command = connection.processOneCommand(
    this);

    ···
    }

    ZygoteConnection#processOneCommand

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Runnable processOneCommand(ZygoteServer zygoteServer) {
    ...
    //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
    .mTargetSdkVersion);
    ...
    }

    现在我们来看看进程fork是如何做的。

    Zygote#forkAndSpecialize

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    public static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
    int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
    int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
    int targetSdkVersion) {
    // fork之前执行的操作
    ZygoteHooks.preFork();
    // 重新设置线程优先级
    resetNicePriority();
    // fork创建进程
    int pid = nativeForkAndSpecialize(
    uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
    fdsToIgnore, startChildZygote, instructionSet, appDataDir);
    ···
    // fork之后需要执行的操作
    ZygoteHooks.postForkCommon();
    return pid;
    }

    此方法将fork分为了三步:preFork、nativeForkAndSpecialize和postForkCommon,其中nativeForkAndSpecialize为真正执行fork的步骤。

    ZygoteHooks#preFork

    libcore/dalvik/src/main/java/dalvik/system/ZygoteHooks.java

    1
    2
    3
    4
    5
    6
    7
    8
    public static void preFork() {
    // 停止守护线程
    Daemons.stop();
    // 完成gc堆的初始化工作
    token = nativePreFork();
    // 等待所有线程停止
    waitUntilAllThreadsStopped();
    }

    由于Dalvik虚拟机的存在,Zygote中除了主线程外还运行了几条守护线程:

  • Java堆内存整理线程:HeapTaskDaemon
  • 引用队列处理线程:ReferenceQueueDaemon
  • 执行finalize()方法的析构线程:FinalizerDaemon
  • 析构方法监控线程:FinalizerWatchdogDaemon
  • 在fork前需要将这些守护线程停止。

    Daemons#stop

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    private static final Daemon[] DAEMONS = new Daemon[] {
    HeapTaskDaemon.INSTANCE,
    ReferenceQueueDaemon.INSTANCE,
    FinalizerDaemon.INSTANCE,
    FinalizerWatchdogDaemon.INSTANCE,
    };

    public static void stop() {
    for (Daemon daemon : DAEMONS) {
    daemon.stop();
    }
    }

    可以看到与上图中的是一致的。

    nativePreFork

    此方法通过JNI最终调用到了dalvik_system_ZygoteHooks.cc中的ZygoteHooks_nativePreFork方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    static jlong ZygoteHooks_nativePreFork(JNIEnv* env, jclass) {
    Runtime* runtime = Runtime::Current();
    // 检查当前Runtime是否为Zygtoe
    CHECK(runtime->IsZygote()) << "runtime instance not started with -Xzygote";

    runtime->PreZygoteFork();

    // 将线程转换为long型并保存到token,该过程是非线程安全的
    return reinterpret_cast<jlong>(ThreadForEnv(env));
    }

    PreZygoteFork定义在runtime.cc中:

    art/runtime/runtime.cc

    1
    2
    3
    4
    5
    6
    7
    8
    9
    void Runtime::PreZygoteFork() {
    if (GetJit() != nullptr) {
    // 完成JIT编译器fork前的工作
    GetJit()->PreZygoteFork();
    }
    // 完成GC堆fork前的工作
    heap_->PreZygoteFork();
    }

    这里不再深入到虚拟机中。

    waitUntilAllThreadsStopped

    1
    2
    3
    4
    5
    6
    7
    private static void waitUntilAllThreadsStopped() {
    File tasks = new File("/proc/self/task");
    // 如果当前不为单线程,继续等待,直到单线程才退出循环
    while (tasks.list().length > 1) {
    Thread.yield();
    }
    }

    此方法会等待当前进程的线程数量为1才会退出。

    ZygoteHooks.preFork()的主要工作便是停止Zygote的4个Daemon子线程的运行,等待并确保Zygote是单线程,并等待这些线程的停止,初始化gc堆的工作,并将线程转换为long型并保存到token中,以便后续能恢复准备线程。

    Zygote#nativeForkAndSpecialize

    nativeForkAndSpecialize通过JNI最终调用如下方法:

    frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
    JNIEnv* env, jclass, jint uid, jint gid, jintArray gids,
    jint runtime_flags, jobjectArray rlimits,
    jint mount_external, jstring se_info, jstring nice_name,
    jintArray managed_fds_to_close, jintArray managed_fds_to_ignore, jboolean is_child_zygote,
    jstring instruction_set, jstring app_data_dir) {
    // 处理蓝牙进程和网络进程相关问题
    jlong capabilities = CalculateCapabilities(env, uid, gid, gids, is_child_zygote);

    if (UNLIKELY(managed_fds_to_close == nullptr)) {
    ZygoteFailure(env, "zygote", nice_name, "Zygote received a null fds_to_close vector.");
    }

    // 将Java数组转换为Vector
    std::vector<int> fds_to_close =
    ExtractJIntArray(env, "zygote", nice_name, managed_fds_to_close).value();
    std::vector<int> fds_to_ignore =
    ExtractJIntArray(env, "zygote", nice_name, managed_fds_to_ignore)
    .value_or(std::vector<int>());

    // 处理Android 10中USAP功能相关问题
    std::vector<int> usap_pipes = MakeUsapPipeReadFDVector();

    fds_to_close.insert(fds_to_close.end(), usap_pipes.begin(), usap_pipes.end());
    fds_to_ignore.insert(fds_to_ignore.end(), usap_pipes.begin(), usap_pipes.end());

    fds_to_close.push_back(gUsapPoolSocketFD);

    if (gUsapPoolEventFD != -1) {
    fds_to_close.push_back(gUsapPoolEventFD);
    fds_to_ignore.push_back(gUsapPoolEventFD);
    }

    // 执行fork
    pid_t pid = ForkCommon(env, false, fds_to_close, fds_to_ignore);

    if (pid == 0) {
    SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
    capabilities, capabilities,
    mount_external, se_info, nice_name, false,
    is_child_zygote == JNI_TRUE, instruction_set, app_data_dir);
    }
    return pid;
    }

    真正执行fork的过程在ForkCommon方法和SpecializeCommon方法中。

    ForkCommon

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    // 从Zygote fork出公共进程
    static pid_t ForkCommon(JNIEnv* env, bool is_system_server,
    const std::vector<int>& fds_to_close,
    const std::vector<int>& fds_to_ignore) {
    // 设置子进程的signal信号处理函数
    SetSignalHandlers();

    // 失败处理函数
    auto fail_fn = std::bind(ZygoteFailure, env, is_system_server ? "system_server" : "zygote",
    nullptr, _1);

    // 临时block住子进程SIGCHLD信号,信号处理导致出错
    BlockSignal(SIGCHLD, fail_fn);

    // 关闭所有日志相关的文件描述符
    __android_log_close();
    stats_log_close();

    // 如果是当前zygote第一次fork,创建文件描述符表
    if (gOpenFdTable == nullptr) {
    gOpenFdTable = FileDescriptorTable::Create(fds_to_ignore, fail_fn);
    } else {
    // 否则判断需要ignore的文件描述与表中是否有变化
    gOpenFdTable->Restat(fds_to_ignore, fail_fn);
    }

    android_fdsan_error_level fdsan_error_level = android_fdsan_get_error_level();

    // 执行fork
    pid_t pid = fork();

    if (pid == 0) {
    // 如果pid为0,则此时为子进程
    // 应用进程的预初始化工作
    PreApplicationInit();

    // 清除需要关闭的文件描述符
    DetachDescriptors(env, fds_to_close, fail_fn);

    // 清除Usap表
    ClearUsapTable();

    // 重新打开所有之前打开的文件描述符
    gOpenFdTable->ReopenOrDetach(fail_fn);

    android_fdsan_set_error_level(fdsan_error_level);
    } else {
    ALOGD("Forked child process %d", pid);
    }

    // fork结束,Unblock子进程SIGCHLD信号
    UnblockSignal(SIGCHLD, fail_fn);

    return pid;
    }

    在fork之前,还需要处理子进程信号和文件描述符问题。对于文件描述符有两个数组,fds_to_close中存放子进程需要关闭的文件描述符,fds_to_ignore中存放子进程需要继承的文件描述符,不过子进程会重新打开这些文件描述符,因此与Zygote并不是共享的。

    真正执行fork操作的是fork()函数,我们重点分析这个方法。

    fork

    fork采用 copy-on-write 技术,这是linux创建进程的标准方法,调用一次,返回两次,返回值有3种类型:

  • 在父进程中,fork返回新创建的子进程pid。
  • 在子进程中,fork返回0;
  • 当出现错误时,fork返回负数。
  • fork的主要工作是寻找空闲的进程号pid,然后从父进程拷贝进程信息,例如数据段和代码段,fork()后子进程要执行的代码等。

    Zygote进程是所有Android进程的母体,包括system_server和各个App进程。

    Zygote利用fork方法生成新进程,对于新进程A复用Zygote进程本身的资源,再加上新进程A相关的资源,构成新的应用进程A。

    copy-on-write过程:

    当父子进程任一方修改内存数据时(这是on-write时机),才发生缺页中断,从而分配新的物理内存(这是copy操作)。

    copy-on-write原理:

    写时拷贝是指子进程与父进程的页表都所指向同一个块物理内存,fork过程只拷贝父进程的页表,并标记这些页表是只读的。父子进程共用同一份物理内存,如果父子进程任一方想要修改这块物理内存,那么会触发缺页异常(page fault),Linux收到该中断便会创建新的物理内存,并将两个物理内存标记设置为可写状态,从而父子进程都有各自独立的物理内存。

    了解到上述知识后,来看看fork的代码:

    bionic/libc/bionic/fork.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    int fork() {
    // 父进程回调此方法完成准备工作
    __bionic_atfork_run_prepare();

    pthread_internal_t* self = __get_thread();

    // clone是一个系统调用
    int result = clone(nullptr,
    nullptr,
    (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD),
    nullptr,
    nullptr,
    nullptr,
    &(self->tid));
    if (result == 0) {
    // 子进程设置缓存pid
    self->set_cached_pid(gettid());

    android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_DISABLED);

    // 子进程回调
    __bionic_atfork_run_child();
    } else {
    // 父进程回调
    __bionic_atfork_run_parent();
    }
    return result;
    }

    在执行clone的前后都有相应的回调方法:

  • __bionic_atfork_run_prepare: fork完成前,父进程回调方法
  • __bionic_atfork_run_child: fork完成后,子进程回调方法
  • __bionic_atfork_run_paren: fork完成后,父进程回调方法
  • 此三个方法的实现都位于bionic/pthread_atfork.cpp中,有需要的话可以扩展这些方法。

    SpecializeCommon

    在fork完成之后,子进程已经创建完毕,此时子进程会调用SpecializeCommon()方法。

    frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids, jint runtime_flags,
    jobjectArray rlimits, jlong permitted_capabilities,
    jlong effective_capabilities, jint mount_external,
    jstring managed_se_info, jstring managed_nice_name,
    bool is_system_server, bool is_child_zygote,
    jstring managed_instruction_set, jstring managed_app_data_dir,
    bool is_top_app, jobjectArray pkg_data_info_list,
    jobjectArray allowlisted_data_info_list, bool mount_data_dirs,
    bool mount_storage_dirs) {

    ···

    if (!is_system_server && getuid() == 0) {
    // 创建进程组
    const int rc = createProcessGroup(uid, getpid());
    if (rc == -EROFS) {
    ALOGW("createProcessGroup failed, kernel missing CONFIG_CGROUP_CPUACCT?");
    } else if (rc != 0) {
    ALOGE("createProcessGroup(%d, %d) failed: %s", uid, /* pid= */ 0, strerror(-rc));
    }
    }

    // 设置Gid
    SetGids(env, gids, is_child_zygote, fail_fn);
    // 设置资源limit
    SetRLimits(env, rlimits, fail_fn);

    if (need_pre_initialize_native_bridge) {
    // Due to the logic behind need_pre_initialize_native_bridge we know that
    // instruction_set contains a value.
    android::PreInitializeNativeBridge(app_data_dir.has_value() ? app_data_dir.value().c_str()
    : nullptr,
    instruction_set.value().c_str());
    }

    if (setresgid(gid, gid, gid) == -1) {
    fail_fn(CREATE_ERROR("setresgid(%d) failed: %s", gid, strerror(errno)));
    }

    SetUpSeccompFilter(uid, is_child_zygote);

    // 设置调度策略
    SetSchedulerPolicy(fail_fn, is_top_app);

    ···

    // 给子进程主线程设置一个名字
    if (nice_name.has_value()) {
    SetThreadName(nice_name.value());
    } else if (is_system_server) {
    SetThreadName("system_server");
    }

    // 恢复对于SIGCHLD信号的处理
    UnsetChldSignalHandler();

    if (is_system_server) {
    env->CallStaticVoidMethod(gZygoteClass, gCallPostForkSystemServerHooks, runtime_flags);
    if (env->ExceptionCheck()) {
    fail_fn("Error calling post fork system server hooks.");
    }

    // TODO(b/117874058): Remove hardcoded label here.
    static const char* kSystemServerLabel = "u:r:system_server:s0";
    if (selinux_android_setcon(kSystemServerLabel) != 0) {
    fail_fn(CREATE_ERROR("selinux_android_setcon(%s)", kSystemServerLabel));
    }
    }

    if (is_child_zygote) {
    initUnsolSocketToSystemServer();
    }

    // 等价于调用Zygote.callPostForkChildHooks
    env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, runtime_flags,
    is_system_server, is_child_zygote, managed_instruction_set);

    // 设置默认进程优先级
    setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_DEFAULT);

    if (env->ExceptionCheck()) {
    fail_fn("Error calling post fork hooks.");
    }
    }

    CallStaticVoidMethod方法使用JNI调用到了Zygote#callPostForkChildHooks方法。

    Zygote#callPostForkChildHooks

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

    1
    2
    3
    4
    5
    private static void callPostForkChildHooks(int runtimeFlags, boolean isSystemServer,
    boolean isZygote, String instructionSet) {
    ZygoteHooks.postForkChild(runtimeFlags, isSystemServer, isZygote, instructionSet);
    }

    libcore/dalvik/src/main/java/dalvik/system/ZygoteHooks.java

    1
    2
    3
    4
    5
    6
    7
    @libcore.api.CorePlatformApi
    public static void postForkChild(int runtimeFlags, boolean isSystemServer, boolean isZygote,
    String instructionSet) {
    nativePostForkChild(token, runtimeFlags, isSystemServer, isZygote, instructionSet);

    Math.setRandomSeedInternal(System.currentTimeMillis());
    }

    这里设置了进程的随机数种子为当前系统时间。

    nativePostForkChild

    art/runtime/native/dalvik_system_ZygoteHooks.cc

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    static void ZygoteHooks_nativePostForkChild(JNIEnv* env,
    jclass,
    jlong token,
    jint runtime_flags,
    jboolean is_system_server,
    jboolean is_zygote,
    jstring instruction_set) {
    DCHECK(!(is_system_server && is_zygote));

    // 从之前保存的token中获得Thread对象
    Thread* thread = reinterpret_cast<Thread*>(token);
    // 重新设置线程tid
    thread->InitAfterFork();
    runtime_flags = EnableDebugFeatures(runtime_flags);

    ···

    // 设置HiddenAPI的执行策略
    api_enforcement_policy = hiddenapi::EnforcementPolicyFromInt(
    (runtime_flags & HIDDEN_API_ENFORCEMENT_POLICY_MASK) >> API_ENFORCEMENT_POLICY_SHIFT);
    runtime_flags &= ~HIDDEN_API_ENFORCEMENT_POLICY_MASK;

    ···

    // GC堆处理fork完成后的工作
    runtime->GetHeap()->PostForkChildAction(thread);
    if (runtime->GetJit() != nullptr) {
    if (!is_system_server) {
    // JIT编译器处理fork完成后的工作
    runtime->GetJit()->GetCodeCache()->PostForkChildAction(
    /* is_system_server= */ false, is_zygote);
    }
    runtime->GetJit()->PostForkChildAction(is_system_server, is_zygote);
    }

    // 验证hiddenAPI策略
    bool do_hidden_api_checks = api_enforcement_policy != hiddenapi::EnforcementPolicy::kDisabled;
    DCHECK(!(is_system_server && do_hidden_api_checks))
    << "SystemServer should be forked with EnforcementPolicy::kDisable";
    DCHECK(!(is_zygote && do_hidden_api_checks))
    << "Child zygote processes should be forked with EnforcementPolicy::kDisable";
    runtime->SetHiddenApiEnforcementPolicy(api_enforcement_policy);
    runtime->SetDedupeHiddenApiWarnings(true);
    if (api_enforcement_policy != hiddenapi::EnforcementPolicy::kDisabled &&
    runtime->GetHiddenApiEventLogSampleRate() != 0) {
    std::srand(static_cast<uint32_t>(NanoTime()));
    }

    if (is_zygote) {
    return;
    }

    if (instruction_set != nullptr && !is_system_server) {
    ScopedUtfChars isa_string(env, instruction_set);
    InstructionSet isa = GetInstructionSetFromString(isa_string.c_str());
    Runtime::NativeBridgeAction action = Runtime::NativeBridgeAction::kUnload;
    if (isa != InstructionSet::kNone && isa != kRuntimeISA) {
    action = Runtime::NativeBridgeAction::kInitialize;
    }
    // app进程执行此方法初始化
    runtime->InitNonZygoteOrPostFork(env, is_system_server, action, isa_string.c_str());
    } else {
    runtime->InitNonZygoteOrPostFork(
    env,
    is_system_server,
    Runtime::NativeBridgeAction::kUnload,
    /*isa=*/ nullptr,
    profile_system_server);
    }
    }

    Runtime#InitNonZygoteOrPostFork

    art/runtime/runtime.cc

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    void Runtime::InitNonZygoteOrPostFork(
    JNIEnv* env,
    bool is_system_server,
    bool is_child_zygote,
    NativeBridgeAction action,
    const char* isa,
    bool profile_system_server) {

    ···

    // 为GC堆创建线程池
    heap_->CreateThreadPool();

    if (!is_system_server) {
    ScopedTrace timing("CreateThreadPool");
    constexpr size_t kStackSize = 64 * KB;
    constexpr size_t kMaxRuntimeWorkers = 4u;
    const size_t num_workers =
    std::min(static_cast<size_t>(std::thread::hardware_concurrency()), kMaxRuntimeWorkers);
    MutexLock mu(Thread::Current(), *Locks::runtime_thread_pool_lock_);
    CHECK(thread_pool_ == nullptr);
    thread_pool_.reset(new ThreadPool("Runtime", num_workers, /*create_peers=*/false, kStackSize));
    thread_pool_->StartWorkers(Thread::Current());
    }

    // 重置gc性能数据,以保证进程在创建之前的GCs不会计算到当前app上。
    heap_->ResetGcPerformanceInfo();
    GetMetrics()->Reset();

    ···

    // 设置信号处理函数
    StartSignalCatcher();

    ···

    // 启动JDWP线程
    GetRuntimeCallbacks()->StartDebugger();
    }

    代码做了大量删减,只需要了解一下即可,不再继续深入。

    ZygoteHooks#postForkCommon

    在执行完fork操作后,我们需要恢复之前停止的几条守护线程。

    libcore/dalvik/src/main/java/dalvik/system/ZygoteHooks.java

    1
    2
    3
    4
    5
    6
    public static void postForkCommon() {
    // 在恢复守护线程之前通知一下Runtime
    nativePostZygoteFork();
    Daemons.startPostZygoteFork();
    }

    Runtime#PostZygoteFork

    art/runtime/runtime.cc

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void Runtime::PostZygoteFork() {
    jit::Jit* jit = GetJit();
    if (jit != nullptr) {
    jit->PostZygoteFork();
    // 确保JIT中的线程有足够的优先级
    if (kIsDebugBuild && jit->GetThreadPool() != nullptr) {
    jit->GetThreadPool()->CheckPthreadPriority(jit->GetThreadPoolPthreadPriority());
    }
    }
    // 重设所有状态
    ResetStats(0xFFFFFFFF);
    }

    Daemons#startPostZygoteFork

    libcore/libart/src/main/java/java/lang/Daemons.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    public static void startPostZygoteFork() {
    postZygoteFork = true;
    for (Daemon daemon : DAEMONS) {
    daemon.startPostZygoteFork();
    }
    }

    public synchronized void startPostZygoteFork() {
    postZygoteFork = true;
    startInternal();
    }

    public void startInternal() {
    if (thread != null) {
    throw new IllegalStateException("already running");
    }
    thread = new Thread(ThreadGroup.systemThreadGroup, this, name);
    thread.setDaemon(true);
    thread.setSystemDaemon(true);
    thread.start();
    }

    小结

    本节中的内容都在Zygote进程中,主要做了以下工作:

  • Zygote通过Socket接收到SystemServer传递过来的创建进程请求。
  • Zygote通过Zygote.forkAndSpecialize方法创建子进程,这又分为几个步骤:
  •