eaaomk

eaaomk eaaomk
主页
博客
  • 常用命令
  • 情景再现
  • AMS
  • Zygote
  • 审计
  • 财务会计
  • 进程与线程
  • 消息传递
  • 处理机调度与死锁
  • 设计思想与代码质量优化
  • 设计模式
  • 数据结构
  • 算法
  • VSCODE
标签
时间轴
关于
author-avatar

eaaomk

37

文章

10

标签

主页
博客
  • 常用命令
  • 情景再现
  • AMS
  • Zygote
  • 审计
  • 财务会计
  • 进程与线程
  • 消息传递
  • 处理机调度与死锁
  • 设计思想与代码质量优化
  • 设计模式
  • 数据结构
  • 算法
  • VSCODE
标签
时间轴
关于

Launcher 程序的启动

Launcher 程序的启动

eaaomk 2021-12-31 23:00:00 JavaAndroid

# Launcher 程序的启动

在认识AMS对Activity的管理与调度之前,建议先认识一下Launcher 程序的启动。 Launcher程序就是我们的桌面程序,桌面程序是一直运行的,那如果用户结束了这个桌面程序,那就没桌面可返回了,那显然是不会的。 那么系统启动这第一个App程序是在哪里呢?请往下接着看源码:

//frameworks/base/services/java/com/android/server/SystemServer.java
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
    ...
    mActivityManagerService.systemReady(() -> {
        Slog.i(TAG, "Making services ready");
        t.traceBegin("StartActivityManagerReadyPhase");
        mSystemServiceManager.startBootPhase(t, SystemService.PHASE_ACTIVITY_MANAGER_READY);
        t.traceEnd();
        // 开启Crash监控
        try {
            mActivityManagerService.startObservingNativeCrashes();
        } catch (Throwable e) {
            reportWtf("observing native crashes", e);
        }
        ...
        // PMS扫描所有包信息
        mPackageManagerService.waitForAppDataPrepared();
        ...
        mSystemServiceManager.startBootPhase(t, SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
        ...

    }, t);
}
  • 开启了必要的服务后,再执行AMS中systemReady的后面一部分代码,传递进去的这个Runnable实际上就是一个前提处理,systemReady方法会先执行这部分代码,再执行后面的一系列流程启动Launcher App.接着往下准备桌面也就是主页的一些信息。
//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
synchronized (this) {
    ...
    t.traceBegin("startPersistentApps");
    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
    t.traceEnd();
    ...
    mBooting = true;
    //为系统用户启用主页活动,以便系统始终启动。当系统用户未设置时,我们不会这样做,因为在这种情况下,设置rd应该是处理家庭活动的rd
    if (UserManager.isSplitSystemUser() &&
            Settings.Secure.getInt(mContext.getContentResolver(),
                Settings.Secure.USER_SETUP_COMPLETE, 0) != 0
            || SystemProperties.getBooleanTEM_USER_HOME_NEEDED, false)) {
        t.traceBegin("enableHomeActivity");
        ComponentName cName = new ComponentName(mContext, emUserHomeActivity.class);
        try {
            AppGlobals.getPackageManager().omponentEnabledSetting(cName,
                    PackageManager.ONENT_ENABLED_STATE_ENABLED, 0,
                    UserHandle.USER_SYSTEM);
        } catch (RemoteException e) {
            throw e.rethrowAsRuntimeException();
        }
        t.traceEnd();
    }

    if (bootingSystemUser) {
        // 开始启动桌面App
        mAtmInternal.startHomeOnAllDisplays(currentUserId, "stemReady");
    }
}
  • 调用mAtmInternal启动app,实际上它的实现就是ATMS,最终调用的还是ATMS中的方法,那么下方的代码中出现了熟悉的身影 mRootWindowContainer ,如果对这个不了解的读者,请移步阅读 Activity任务栈 ,这里继续向下调用mRootWindowContainer的startHomeOnAllDisplays方法。
  • 可能读者比较好奇,这些数据是什么时候初始化的呢?别忘了之前一系列的ready工作,它的内部就是在做这些准备。
//frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@Override
public boolean startHomeOnAllDisplays(int userId, String reason) {
    synchronized (mGlobalLock) {
        return mRootWindowContainer.startHomeOnAllDisplays(userId, reason);
    }
}
  • 定义homeStarted 作为启动结果的存储,getChildAt函数是在获取DisplayContent的id。
//frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
boolean startHomeOnAllDisplays(int userId, String reason) {
    boolean homeStarted = false;
    for (int i = getChildCount() - 1; i >= 0; i--) {
        final int displayId = getChildAt(i).mDisplayId;
        // 获取一个displayId,继续向下调用
        homeStarted |= startHomeOnDisplay(userId, reason, displayId);
    }
    return homeStarted;
}

boolean startHomeOnDisplay(int userId, String reason, int displayId) {
        return startHomeOnDisplay(userId, reason, displayId, false /* allowInstrumenting */,
                false /* fromHomeKey */);
}

boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
        boolean fromHomeKey) {
    // 获取最上层的有焦点的display,或者默认的display(如果传入的这个displayId是无效的)
    if (displayId == INVALID_DISPLAY) {
        final ActivityStack stack = getTopDisplayFocusedStack();
        displayId = stack != null ? stack.getDisplayId() : DEFAULT_DISPLAY;
    }
    // 根据id取得DisplayContent
    final DisplayContent display = getDisplayContent(displayId);
    boolean result = false;
    for (int tcNdx = display.getTaskDisplayAreaCount() - 1; tcNdx >= 0; --tcNdx) {
        // 从DisplayAreaPolicy中取出一个TaskDisplayArea
        final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tcNdx);
        result |= startHomeOnTaskDisplayArea(userId, reason, taskDisplayArea,
                allowInstrumenting, fromHomeKey);
    }
    return result;
}

// 最终执行到了这里
boolean startHomeOnTaskDisplayArea(int userId, String reason, TaskDisplayArea taskDisplayArea,
        boolean allowInstrumenting, boolean fromHomeKey) {
    // 做非空判断
    if (taskDisplayArea == null) {
        final ActivityStack stack = getTopDisplayFocusedStack();
        taskDisplayArea = stack != null ? stack.getDisplayArea()
                : getDefaultTaskDisplayArea();
    }
    ...
    Intent homeIntent = null;
    ActivityInfo aInfo = null;
    // 找到这个对应的HomeActivity的信息,做一些准备
    if (taskDisplayArea == getDefaultTaskDisplayArea()) {
        homeIntent = mService.getHomeIntent();
        aInfo = resolveHomeActivity(userId, homeIntent);
    } else if (shouldPlaceSecondaryHomeOnDisplayArea(taskDisplayArea)) {
        Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, taskDisplayArea);
        aInfo = info.first;
        homeIntent = info.second;
    }
    ...
    final String myReason = reason + ":" + userId + ":" + UserHandle.getUserId(
            aInfo.applicationInfo.uid) + ":" + taskDisplayArea.getDisplayId();
    //调用ATMS 中的 ActivityStartController 开始启动HomeActivity
    mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
            taskDisplayArea);
    return true;
}
//frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java
void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason,
            TaskDisplayArea taskDisplayArea) {
        ...
        final ActivityStack homeStack;
        try {
            // 确保有一个ActivityStack 存在于taskDisplayArea中
            homeStack = taskDisplayArea.getOrCreateRootHomeTask(ON_TOP);
        } finally {
            mSupervisor.endDeferResume();
        }
        //获取一个Starter 处理事件,最终执行是在execute() 方法中;
        mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
                .setOutActivity(tmpOutRecord)
                .setCallingUid(0)
                .setActivityInfo(aInfo)
                .setActivityOptions(options.toBundle())
                .execute();
        ...
    }
  • 接下来的流程就与我们平时启动一个普通Activity一样。

# 普通Activity的启动流程

// frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
int execute() {
    try{
        ...
        synchronized (mService.mGlobalLock) {
            ...
            //处理这个请求
            res = executeRequest(mRequest);
            ...
        }
        ...
    }finally{
        onExecutionComplete();
    }
}

private int executeRequest(Request request) {
    ...
    // 向下调用
    mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
            request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
            restrictedBgActivity, intentGrants);
    ...
}

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                int startFlags, boolean doResume, ActivityOptions options, Task inTask,
                boolean restrictedBgActivity, NeededUriGrants intentGrants) {
    int result = START_CANCELED;
    final ActivityStack startedActivityStack;
    try {
        ...
        // 继续在这里向下调用
        result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
                startFlags, doResume, options, inTask, restrictedBgActivity, ntGrants);
    } finally {
        ...
    }

    postStartActivityProcessing(r, result, startedActivityStack);

    return result;
}

int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
              IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
              int startFlags, boolean doResume, ActivityOptions options, Task inTask,
              boolean restrictedBgActivity, NeededUriGrants intentGrants) {
          setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, eSession,
                  voiceInteractor, restrictedBgActivity);
  
    computeLaunchingTaskFlags();

    computeSourceStack(); // 计算让哪一个ActivityStack去启动这个Activity

    mIntent.setFlags(mLaunchFlags);
    ...
    final boolean newTask = targetTask == null;
    mTargetTask = targetTask;
    ...
    if (newTask) {
        // 如果它是一个新的Task,则将其放入,注意我们这里加入的是一个ActivityTask(ActivityTask继承至Task类)
        final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
                ? mSourceRecord.getTask() : null;
        setNewTask(taskToAffiliate);
    } else if (mAddingToTask) {
        // 或者需要加入Task
        addOrReparentStartingActivity(targetTask, "adding to task");
    }

    if (mDoResume) {
        final ActivityRecord topTaskActivity =
                mStartActivity.getTask().topRunningActivityLocked();
        if (!mTargetStack.isTopActivityFocusable()
                || (topTaskActivity != null && topTaskActivity.isTaskOverlay()
                && mStartActivity != topTaskActivity)) {
            ...
        } else {
            ...
            /// 执行启动Activity的流程
            mRootWindowContainer.resumeFocusedStacksTopActivities(
                    mTargetStack, mStartActivity, mOptions);
        }
    }
    
    ...
    // 更新栈
    mRootWindowContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);

    // Update the recent tasks list immediately when the activity starts
    // 放入mRecentTasks中
    mSupervisor.mRecentTasks.add(mStartActivity.getTask());
    mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(),
            mPreferredWindowingMode, mPreferredTaskDisplayArea, mTargetStack);

    return START_SUCCESS;
}
//frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
boolean resumeFocusedStacksTopActivities(
    ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
    ....
    for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
        boolean resumedOnDisplay = false;
        final DisplayContent display = getChildAt(displayNdx);
        ....
        if (!resumedOnDisplay) {
            final ActivityStack focusedStack = display.getFocusedStack();
            if (focusedStack != null) {
                // 不为空,则调用resumeTopActivityUncheckedLocked函数
                result |= focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
            } else if (targetStack == null) {
                //如果目标栈为空,则返回桌面应用程序
                result |= resumeHomeActivity(null /* prev */, "no-focusable-task",
                        display.getDefaultTaskDisplayArea());
            }
        }
    }
    return result;
}
//frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
    if (mInResumeTopActivity) {
        // Don't even start recursing.
        return false;
    }

    boolean result = false;
    try {
        ...
        //使用之前计算出来的栈进行启动Activity
        result = resumeTopActivityInnerLocked(prev, options);
        ...
    } finally {
        mInResumeTopActivity = false;
    }
    return result;
}

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    if (!mAtmService.isBooting() && !mAtmService.isBooted()) {
        // Not ready yet!
        return false;
    }
    ...
        boolean pausing = taskDisplayArea.pauseBackStacks(userLeaving, next);
    if (mResumedActivity != null) {
        if (DEBUG_STATES) Slog.d(TAG_STATES,
                "resumeTopActivityLocked: Pausing " + mResumedActivity);
        // 通知Launcher进入Pause状态,在它进入这个状态后,在ActivityStackSupervisor的startSpecificActivity方法里判断新的app进程状态做出不同响应
        pausing |= startPausingLocked(userLeaving, false /* uiSleeping */, next);
    }

    ...
    if (next.attachedToProcess()) {
        ...
    }
    else{
        ...
        if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
        // 调用ActivityStackSupervisor启动Activity
        mStackSupervisor.startSpecificActivity(next, true, true);
    }
}
  • 判断该应用的进程是否存在,这里会出现一个分支分为两个方向,如果进程不存在(一般情况下,创建这个应用程序的第一个Activity会创建一个新的进程),那么将会创建一个新的进程,下文将会
// frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
    // Is this activity's application already running?
    // 获取应用的进程信息
    final WindowProcessController wpc =
            mService.getProcessController(r.processName, r.info.applicationInfo.uid);

    boolean knownToBeDead = false;
    
    if (wpc != null && wpc.hasThread()) {
        try {
            //如果进程存在,并且进程中有线程存在,就启动一个同应用的activity
            realStartActivityLocked(r, wpc, andResume, checkConfig);
            // 这里直接返回
            return;
        } catch (RemoteException e) {
            Slog.w(TAG, "Exception when starting activity "
                    + r.intent.getComponent().flattenToShortString(), e);
        }

        // If a dead object exception was thrown -- fall through to
        // restart the application.
        knownToBeDead = true;
    }
    r.notifyUnknownVisibilityLaunchedForKeyguardTransition();
    final boolean isTop = andResume && r.isTopRunningActivity();
    // 如果上面没有返回,就代表进程不存在,则需要通过AMS向Zygote进程请求创建新进程
    mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
}

# 创建新进程

  • 这里的mH 中的Looper 是AMS在初始化中调用了ATMS的initialize函数,它来自于 DisplayThread.get().getLooper() ||DisplayThread它是一个单例,DisplayThread又是在SystemServer中调用了 Looper.prepareMainLooper(),进行了looper的初始化,所以这里发送消息,相当于将时间交给了SystemServer线程处理,最后调用ActivityManagerInternal的startProcess方法,但是ActivityManagerInternal是一个抽象类,它最终的实现是AMS中的LocalService。
//frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop,
        String hostingType) {
    try {
        if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "dispatchingStartProcess:"
                    + activity.processName);
        }
        // Post message to start process to avoid possible deadlock of calling into AMS with the
        // ATMS lock held.
        // 这里采取的是通过Handler方式发送消息,实现线程的切换
        // 如果读者对Handler不能理解,请查阅Handler部分的解读
        final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,
                mAmInternal, activity.processName, activity.info.applicationInfo, knownToBeDead,
                isTop, hostingType, activity.intent.getComponent());
        // 发送消息
        mH.sendMessage(m);
    } finally {
        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
    }
}

//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java //LocalService Class
@Override
public void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead,
                            boolean isTop, String hostingType, ComponentName hostingName) {
    try {
        if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "startProcess:"
                    + processName);
        }
        synchronized (ActivityManagerService.this) {
            // 开启进程
            startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
                    new HostingRecord(hostingType, hostingName, isTop),
                    ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE, false /* allowWhileBooting */,
                    false /* isolated */, true /* keepIfLarge */);
        }
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    }
}
//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@GuardedBy("this")
final ProcessRecord startProcessLocked(String processName,ApplicationInfo info, 
    boolean knownToBeDead, int intentFlags,HostingRecord hostingRecord, 
    int zygotePolicyFlags, boolean allowWhileBooting,boolean isolated, boolean keepIfLarge) {

    return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
            hostingRecord, zygotePolicyFlags, allowWhileBooting, isolated, 0 /* isolatedUid */,
            keepIfLarge, null /* ABI override */, null /* entryPoint */,
            null /* entryPointArgs */, null /* crashHandler */);
}
//frameworks/base/services/core/java/com/android/server/am/ProcessList.java
@GuardedBy("mService")
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
        boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
        int zygotePolicyFlags, boolean allowWhileBooting, boolean isolated, int isolatedUid,
        boolean keepIfLarge, String abiOverride, String entryPoint, String[] entryPointArgs,
        Runnable crashHandler) {
    long startTime = SystemClock.uptimeMillis();
    ProcessRecord app;
    ... //这里省去的代码是检查存在可复用的进程
  
    ///创建ProcessRecord对象,它保存了当前正在运行的特定进程的完整信息,也就是需要启动的应用程序进程,接着继续调用startProcessLocked方法
    if (app == null) {
        checkSlow(startTime, "startProcess: creating new process record");
        app = newProcessRecordLocked(info, processName, isolated, isolatedUid, hostingRecord);
        ....
        checkSlow(startTime, "startProcess: done creating new process record");
    } else {
        // If this is a new package in the process, add the package to the list
        app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
        checkSlow(startTime, "startProcess: added package to existing proc");
    }
    ...
    // 这里继续向下调用
    final boolean success =
            startProcessLocked(app, hostingRecord, zygotePolicyFlags, abiOverride);
    checkSlow(startTime, "startProcess: done starting proc!");
    return success ? app : null;
}

 @GuardedBy("mService")
boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
        int zygotePolicyFlags, boolean disableHiddenApiChecks, boolean disableTestApiChecks,
        boolean mountExtStorageFull, String abiOverride) {
     try {
         ...
         // 继续向下调用
        boolean startSuccess =  startProcessLocked(hostingRecord, entryPoint,
                    app, uid, gids, runtimeFlags, zygotePolicyFlags, 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;
    }
}

@GuardedBy("mService")
boolean startProcessLocked(HostingRecord hostingRecord, String entryPoint, ProcessRecord app,
        int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags, int mountExternal,
        String seInfo, String requiredAbi, String instructionSet, String invokeWith,
        long startTime) {
    ...

    if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
        ...
    } else {
        try {
            // 继续调用startProcess方法
            final Process.ProcessStartResult startResult = startProcess(hostingRecord,
                    entryPoint, app,
                    uid, gids, runtimeFlags, zygotePolicyFlags, 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 app.pid > 0;
    }
}

private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags,
            int mountExternal, String seInfo, String requiredAbi, String instructionSet,
            String invokeWith, long startTime) {
    try {
        ...
        Process.ProcessStartResult startResult;
        // 根据启动的不同类型的App,有不同的创建进程的方式
        if (hostingRecord.usesWebviewZygote()) {
        //启动webview进程
            startResult = startWebView(entryPoint,
                    app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                    app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                    app.info.dataDir, null, app.info.packageName, app.mDisabledCompatChanges,
                    new String[]{PROC_START_SEQ_IDENT + app.startSeq});
        } else if (hostingRecord.usesAppZygote()) {
            // 处理用户AppZygote
            final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);

            // We can't isolate app data and storage data as parent zygote already did that.
            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,
                    /*zygotePolicyFlags=*/ ZYGOTE_POLICY_FLAG_EMPTY, isTopApp,
                    app.mDisabledCompatChanges, pkgDataInfoMap, whitelistedAppDataInfoMap,
                    false, false,
                    new String[]{PROC_START_SEQ_IDENT + app.startSeq});
        } else {
            //新创建的应用程序进程 
            //modify for prefork blank process begin
            PreForkArgs preforkArgs = new PreForkArgs(entryPoint,
                    app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                    app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                    app.info.dataDir, invokeWith, app.info.packageName, zygotePolicyFlags,
                    isTopApp, app.mDisabledCompatChanges, pkgDataInfoMap,
                    whitelistedAppDataInfoMap, bindMountAppsData, bindMountAppStorageDirs,
                    new String[] {PROC_START_SEQ_IDENT + app.startSeq});
            startResult = mService.handlePreForkStartProcess(preforkArgs);
            if (startResult == null) {
                // 调用了Process 的 start方法 开启新进程
                startResult = Process.start(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, invokeWith, app.info.packageName, zygotePolicyFlags,
                        isTopApp, app.mDisabledCompatChanges, pkgDataInfoMap,
                        whitelistedAppDataInfoMap, bindMountAppsData, bindMountAppStorageDirs,
                        new String[]{PROC_START_SEQ_IDENT + app.startSeq});
            }
            ...
            //modify for prefork blank process end
        }
        checkSlow(startTime, "startProcess: returned from zygote!");
        return startResult;
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    }
}

# 向Zygote申请创建进程

//frameworks/base/core/java/android/os/Process.java
public static ProcessStartResult start(@NonNull final String processClass,
                                           @Nullable final String niceName,
                                           int uid, int gid, @Nullable int[] gids,
                                           int runtimeFlags,
                                           int mountExternal,
                                           int targetSdkVersion,
                                           @Nullable String seInfo,
                                           @NonNull String abi,
                                           @Nullable String instructionSet,
                                           @Nullable String appDataDir,
                                           @Nullable String invokeWith,
                                           @Nullable String packageName,
                                           int zygotePolicyFlags,
                                           boolean isTopApp,
                                           @Nullable long[] disabledCompatChanges,
                                           @Nullable Map<String, Pair<String, Long>>
                                                   pkgDataInfoMap,
                                           @Nullable Map<String, Pair<String, Long>>
                                                   whitelistedDataInfoMap,
                                           boolean bindMountAppsData,
                                           boolean bindMountAppStorageDirs,
                                           @Nullable String[] zygoteArgs) {
        // 向zygote 进程发送开启新进程的请求
    return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
                runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                abi, instructionSet, appDataDir, invokeWith, packageName,
                zygotePolicyFlags, isTopApp, disabledCompatChanges,
                pkgDataInfoMap, whitelistedDataInfoMap, bindMountAppsData,
                bindMountAppStorageDirs, zygoteArgs);
    }
//frameworks/base/core/java/android/os/ZygoteProcess.java
public final Process.ProcessStartResult start(@NonNull final String processClass,
                                                final String niceName,
                                                int uid, int gid, @Nullable int[] gids,
                                                int runtimeFlags, int mountExternal,
                                                int targetSdkVersion,
                                                @Nullable String seInfo,
                                                @NonNull String abi,
                                                @Nullable String instructionSet,
                                                @Nullable String appDataDir,
                                                @Nullable String invokeWith,
                                                @Nullable String packageName,
                                                int zygotePolicyFlags,
                                                boolean isTopApp,
                                                @Nullable long[] disabledCompatChanges,
                                                @Nullable Map<String, Pair<String, Long>>
                                                        pkgDataInfoMap,
                                                @Nullable Map<String, Pair<String, Long>>
                                                        whitelistedDataInfoMap,
                                                boolean bindMountAppsData,
                                                boolean bindMountAppStorageDirs,
                                                @Nullable String[] zygoteArgs) {
    // TODO (chriswailes): Is there a better place to check this value?
    if (fetchUsapPoolEnabledPropWithMinInterval()) {
        informZygotesOfUsapPoolStatus();
    }

    try {
        // 向下继续执行
        return startViaZygote(processClass, niceName, uid, gid, gids,
                runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,
                packageName, zygotePolicyFlags, isTopApp, disabledCompatChanges,
                pkgDataInfoMap, whitelistedDataInfoMap, bindMountAppsData,
                bindMountAppStorageDirs, zygoteArgs);
    } catch (ZygoteStartFailedEx ex) {
        Log.e(LOG_TAG,
                "Starting VM process through Zygote failed");
        throw new RuntimeException(
                "Starting VM process through Zygote failed", ex);
    }
}


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,
                                                    int zygotePolicyFlags,
                                                    boolean isTopApp,
                                                    @Nullable long[] disabledCompatChanges,
                                                    @Nullable Map<String, Pair<String, Long>>
                                                            pkgDataInfoMap,
                                                    @Nullable Map<String, Pair<String, Long>>
                                                            whitelistedDataInfoMap,
                                                    boolean bindMountAppsData,
                                                    boolean bindMountAppStorageDirs,
                                                    @Nullable String[] extraArgs)
                                                    throws ZygoteStartFailedEx {
    ArrayList<String> argsForZygote = new ArrayList<>();

    // --runtime-args, --setuid=, --setgid=,
    // and --setgroups= must go first
    argsForZygote.add("--runtime-args");
    argsForZygote.add("--setuid=" + uid);
    argsForZygote.add("--setgid=" + gid);
    argsForZygote.add("--runtime-flags=" + runtimeFlags);
    .... // 构造了一堆进程信息

    synchronized(mLock) {
        // The USAP pool can not be used if the application will not use the systems graphics
        // driver.  If that driver is requested use the Zygote application start path.
        // openZygoteSocketIfNeeded 是在打开一个连接口使用
        return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
                                            zygotePolicyFlags,
                                            argsForZygote);
    }
}
@GuardedBy("mLock")
private Process.ProcessStartResult zygoteSendArgsAndGetResult(
        ZygoteState zygoteState, int zygotePolicyFlags, @NonNull ArrayList<String> args)
        throws ZygoteStartFailedEx {
        ...
        ...
    if (shouldAttemptUsapLaunch(zygotePolicyFlags, 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);
}

private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
        ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
    try {
        /// 获取一个BufferedWriter 通过socket 通信向 zygote 进程发送创建进程的信息
        // 获取一个 DataInputStream 通过socket 通信 读取zygote创建进程的结果
        final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
        final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;

        zygoteWriter.write(msgStr);
        zygoteWriter.flush();

        ...
        Process.ProcessStartResult result = new Process.ProcessStartResult();
        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);
    }
}

# Zygote创建进程

  • 如果读者对Zygote进程启动之前的流程不熟悉,请移步阅读Android系统的启动流程。
  • 这里将会探讨Zygote的进程启动后都做了些什么,是framework层面的,并非C/C++(native)层次.
  • 如果读者对fork函数存在疑问请移步阅读fork相关文章
//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
    ZygoteServer zygoteServer = null;

    // Mark zygote start. This ensures that thread creation will throw
    // an error.
    ZygoteHooks.startZygoteNoThreadCreation();

    // Zygote goes into its own process group.
    try {
        Os.setpgid(0, 0);
    } catch (ErrnoException ex) {
        throw new RuntimeException("Failed to setpgid(0,0)", ex);
    }

    Runnable caller;
    try {
        // Store now for StatsLogging later.
        final long startTime = SystemClock.elapsedRealtime();
        final boolean isRuntimeRestarted = "1".equals(
                SystemProperties.get("sys.boot_completed"));

        /// 判断是64位还是32位?
        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])) {
                startSystemServer = true;
            } else if ("--enable-lazy-preload".equals(argv[i])) {
                enableLazyPreload = 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)) {
                zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length());
            } else {
                throw new RuntimeException("Unknown command line argument: " + argv[i]);
            }
        }
        ...
        ...
        // Do an initial gc to clean up after startup
        // 垃圾回收  GC 初始化
        bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
        gcAndFinalize();
        bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC

        bootTimingsTraceLog.traceEnd(); // ZygoteInit

        Zygote.initNativeState(isPrimaryZygote);

        ZygoteHooks.stopZygoteNoThreadCreation();

        /// 创建一个Server 端
        zygoteServer = new ZygoteServer(isPrimaryZygote);

        if (startSystemServer) {
            // fork 一个SystemServer进程
            Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);

            // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
            // child (system_server) process.
            if (r != null) {
                r.run();
                return;
            }
        }

        Log.i(TAG, "Accepting command socket connections");

        // The select loop returns early in the child process after a fork and
        // loops forever in the zygote.
        //循环等待fork出其他的应用进程,比如Launcher
        //最终通过调用processOneCommand()来进行进程的处理
        //监听socket消息,并且获取到java的函数入口,这里zygote会一直循环,能返回的都是fork出来的子进程
        caller = zygoteServer.runSelectLoop(abiList);
    } catch (Throwable ex) {
        Log.e(TAG, "System zygote died with exception", ex);
        throw ex;
    } finally {
        //  返回的子进程并不需要父进程的zygoteServer,这东西对于它们来讲无用,所以在能返回的最后都要执行关闭zygoteServer
        if (zygoteServer != null) {
            zygoteServer.closeServerSocket();
        }
    }

    // We're in the child process and have exited the select loop. Proceed to execute the
    // command.        
    if (caller != null) {
        //执行返回的Runnable对象,进入子进程
        caller.run();
    }
}
  • 创建SystemServer进程
//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
 private static Runnable forkSystemServer(String abiList, String socketName,
            ZygoteServer zygoteServer) {
        ...
        /* 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,1023,"
                        + "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010,3011",
                "--capabilities=" + capabilities + "," + capabilities,
                "--nice-name=system_server",
                "--runtime-args",
                "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
                "com.android.server.SystemServer",
        };
        ZygoteArguments parsedArgs = null;

        int pid;

        try {
            ...
            // 调用native 方法fork新进程
            /* Request to fork the system server process */
            pid = Zygote.forkSystemServer(
                    parsedArgs.mUid, parsedArgs.mGid,
                    parsedArgs.mGids,
                    parsedArgs.mRuntimeFlags,
                    null,
                    parsedArgs.mPermittedCapabilities,
                    parsedArgs.mEffectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }

        /* For child process */
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }
            // 如果是子进程,需要将fork出来的父进程的zygoteServer关闭
            zygoteServer.closeServerSocket();
            return handleSystemServerProcess(parsedArgs);
        }

        return null;
    }
  • 等待SystemServer的消息,创建其他进程,我们这里注意一下runSelectLoop 函数,该函数在接受到创建其他进程时,会走向 connection.processOneCommand() 方法
//frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
Runnable runSelectLoop(String abiList) {
     ...

    while (true) {
        ...
        if (pollReturnValue == 0) {
           ...

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

                if (pollIndex == 0) {
                    // Zygote server socket

                    ZygoteConnection newPeer = acceptCommandPeer(abiList);
                    peers.add(newPeer);
                    socketFDs.add(newPeer.getFileDescriptor());

                } else if (pollIndex < usapPoolEventFDIndex) {
                    // Session socket accepted from the Zygote server socket

                    try {
                        ZygoteConnection connection = peers.get(pollIndex);
                        //这个函数需要重点注意下
                        final Runnable command = connection.processOneCommand(this);

                        // TODO (chriswailes): Is this extra check necessary?
                        if (mIsForkChild) {
                            // We're in the child. We should always have a command to run at
                            // this stage if processOneCommand hasn't called "exec".
                            if (command == null) {
                                throw new IllegalStateException("command == null");
                            }
                            // 在此处进行了返回,主进程会一直卡在此函数,但子进程将会返回command,并且会执行command的run方法
                            return command; 
                        } else {
                            ...
                        }
                    } catch (Exception e) {
                        ...
                    } finally {
                        // Reset the child flag, in the event that the child process is a child-
                        // zygote. The flag will not be consulted this loop pass after the
                        // Runnable is returned.
                        mIsForkChild = false;
                    }

                } else {
                   ...
                }
            }
            ...
        }
        ...
    }
}
  • 这里我们重点注意一下processOneCommand函数
//frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
Runnable processOneCommand(ZygoteServer zygoteServer) {
        String[] args;
        /// 读取传递过来的参数
        try {
            args = Zygote.readArgumentList(mSocketReader);
        } catch (IOException ex) {
            throw new IllegalStateException("IOException on command socket", ex);
        }

        ...
        //fork子进程,调用native方法
        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.mWhitelistedDataInfoList,
                parsedArgs.mBindMountAppDataDirs, parsedArgs.mBindMountAppStorageDirs);

        try {
            if (pid == 0) {
                // in child
                zygoteServer.setForkChild();

                zygoteServer.closeServerSocket();
                IoUtils.closeQuietly(serverPipeFd);
                serverPipeFd = null;
                // 子进程的初始化
                return handleChildProc(parsedArgs, childPipeFd, parsedArgs.mStartChildZygote);
            } else {
                // In the parent. A pid < 0 indicates a failure and will be handled in
                // handleParentProc.
                IoUtils.closeQuietly(childPipeFd);
                childPipeFd = null;
                handleParentProc(pid, serverPipeFd);
                return null;
            }
        } finally {
            IoUtils.closeQuietly(childPipeFd);
            IoUtils.closeQuietly(serverPipeFd);
        }
    }

private Runnable handleChildProc(ZygoteArguments parsedArgs,
        FileDescriptor pipeFd, boolean isZygote) {
    /*
        * By the time we get here, the native code has closed the two actual Zygote
        * socket connections, and substituted /dev/null in their place.  The LocalSocket
        * objects still need to be closed properly.
        */

    closeSocket();

    Zygote.setAppProcessName(parsedArgs, TAG);

    // End of the postFork event.
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    if (parsedArgs.mInvokeWith != null) {
        WrapperInit.execApplication(parsedArgs.mInvokeWith,
                parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
                VMRuntime.getCurrentInstructionSet(),
                pipeFd, parsedArgs.mRemainingArgs);

        // Should not get here.
        throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
    } else {
        if (!isZygote) {
            /// zygoteInit 函数 ,初始化binder 线程池
            return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                    parsedArgs.mDisabledCompatChanges,
                    parsedArgs.mRemainingArgs, null /* classLoader */);
        } else {
            return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
                    parsedArgs.mRemainingArgs, null /* classLoader */);
        }
    }
}
  • 这里深入看一看返回的Runnable
//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
 public static final Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
            String[] argv, ClassLoader classLoader) {
    if (RuntimeInit.DEBUG) {
        Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
    }

    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
    RuntimeInit.redirectLogStreams();

    RuntimeInit.commonInit();
    ZygoteInit.nativeZygoteInit();
    return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
            classLoader);
}
  • 这里会通过对应的信息去搜索 main 方法入口,返回的是MethodAndArgsCaller,该类是RuntimeInit的静态内部类,它的run 方法就是通过反射将参数args 传递进去,并运行这个函数,那么这个函数就是我们ActivityThread类的main方法入口,至此 Zygote 流程结束,接下来将会在ActivityThread 中进行进一步解析和讲解.
  • 如果对Java反射不清楚的读者请移步Java 反射相关文章
  • 如果对Socket通信不清楚的读者请移步Socket 通信相关文章
//frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
 protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
        String[] argv, ClassLoader classLoader) {
    // If the application calls System.exit(), terminate the process
    // immediately without running any shutdown hooks.  It is not possible to
    // shutdown an Android application gracefully.  Among other things, the
    // Android runtime shutdown hooks close the Binder driver, which can cause
    // leftover running threads to crash before the process actually exits.
    nativeSetExitWithoutCleanup(true);

    VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
    VMRuntime.getRuntime().setDisabledCompatChanges(disabledCompatChanges);

    final Arguments args = new Arguments(argv);

    // The end of of the RuntimeInit event (see #zygoteInit).
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

    // Remaining arguments are passed to the start class's static main
    return findStaticMain(args.startClass, args.startArgs, classLoader);
}

 protected static Runnable findStaticMain(String className, String[] argv,
            ClassLoader classLoader) {
    Class<?> cl;

    try {
        cl = Class.forName(className, true, classLoader);
    } catch (ClassNotFoundException ex) {
        throw new RuntimeException(
                "Missing class when invoking static main " + className,
                ex);
    }

    Method m;
    try {
        m = cl.getMethod("main", new Class[] { String[].class });
    } catch (NoSuchMethodException ex) {
        throw new RuntimeException(
                "Missing static main on " + className, ex);
    } catch (SecurityException ex) {
        throw new RuntimeException(
                "Problem getting static main on " + className, ex);
    }

    int modifiers = m.getModifiers();
    if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
        throw new RuntimeException(
                "Main method is not public and static on " + className);
    }

    /*
        * This throw gets caught in ZygoteInit.main(), which responds
        * by invoking the exception's run() method. This arrangement
        * clears up all the stack frames that were required in setting
        * up the process.
        */
    return new MethodAndArgsCaller(m, argv);
}

static class MethodAndArgsCaller implements Runnable {
    /** method to call */
    private final Method mMethod;

    /** argument array */
    private final String[] mArgs;

    public MethodAndArgsCaller(Method method, String[] args) {
        mMethod = method;
        mArgs = args;
    }

    public void run() {
        try {
            // 通过反射调用这个函数
            mMethod.invoke(null, new Object[] { mArgs });
        } catch (IllegalAccessException ex) {
            throw new RuntimeException(ex);
        } catch (InvocationTargetException ex) {
            Throwable cause = ex.getCause();
            if (cause instanceof RuntimeException) {
                throw (RuntimeException) cause;
            } else if (cause instanceof Error) {
                throw (Error) cause;
            }
            throw new RuntimeException(ex);
        }
    }
}