Android9.0 Activity启动流程分析(一)

1、ActivityRecord、TaskRecord、ActivityStack和ActivityDisplay介绍

  本篇文章是基于Android refs/tags/android-9.0.0_r8分支的代码进行分析的
  在分析Activity启动的源码之前先介绍一下Activity的一些基本概念。

1.1 Activity和Task

  关于Android中Activity和Task的介绍,个人觉得《深入理解Android》中的例子不错。我们就借鉴其中的例子,进行相应的说明:
Android9.0 Activity启动流程分析(一)_第1张图片
  上图模拟了用户在Android系统上想干的三件事,分别用A、B、C表示。在Android中,每一件事可以被看作是一个Task;一个Task可以被细分成多个子步骤,每个子步骤可以被看作是一个Activity。

  另外A、B两个Task使用了不同的Activity来完成相应的任务,即A、B两个Task的Activity之间没有复用。但是在Task C中,分别使用了Task A中的A1、Task B中的B2。这么设计的原因是:用户想做的事情(Task)即使完全不同,但是当细分Task为Activity时,就可能出现Activity功能类似的情况。当Task A和Task B中已经有能满足需求的Activity时,Task C就会优先复用而不是重新创建Activity。通过重用Activity可以节省一定的开销,同时为用户提供一致的用户界面。

  对Android的设计理念有一定的了解后,我们看看Android是如何组织Task及它所包含的Activity的。
Android9.0 Activity启动流程分析(一)_第2张图片
  上图为一个比较经典的示例:图中的Task包含4个Activity。用户可以单击按钮跳转到下一个Activity。同时,通过返回键可以回到上一个Activity。图中虚线下方为Activity的组织方式。从图中可以看出,Task是以栈的形式管理Activity的,先启动的Activity成位于栈底,后启动的Activity将作为栈顶成员显示在界面上。

1.2 ActivityRecord、TaskRecord、ActivityStack和ActivityDisplay

  了解了Activity和Task的概念之后我们再看看AMS中的ActivityRecord、TaskRecord、ActivityStack和ActivityDisplay

  1. ActivityRecord:在AMS中ActivityRecord是Activity的代表,ActivityRecord中的成员变量TaskRecord task代表当前Activity所在的栈,那么他的栈信息就保存在TaskRecord中。
  2. TaskRecord:TaskRecord是Task的代表,TaskRecord其中两个成员变量:
      ArrayList mActivities:这个就是当前栈中所管理的Activity的列表
      ActivityStack mStack:他是ActivityRecord和TaskRecord的管理者
  3. ActivityStack:从名字上看,感觉他是真正的栈,但实际上他是一个Manager的角色,他是负责管理协调ActivityRecord和TaskRecord的。ActivityStack中的成员变量ArrayList mTaskHistory记录的是当前ActivityStack管理的所有的栈。
  4. ActivityDisplay:他是显示屏的抽象,每一个ActivityDisplay代表一块屏幕,在开机过程中AMS会根据DisplayManager的Display信息在AMS中创建ActivityDisplay。
    下面是一个简单的关系图

Android9.0 Activity启动流程分析(一)_第3张图片
  可以看到一个ActivityDisplay可以包含多个ActivityStack,ActivityStack也包含很多个TaskRecord,一个TaskRecord又可以包含很多个ActivityRecord。

2、am命令

接下来我们将利用am命令启动一个Activity,来分析Activity的启动流程的源码。

am start -W -n com.android.settings/com.android.settings.Settings

-W:表示等待目标activity启动的返回结果
-n :后接component name用于指定启动的Activity

在shell中输入如上命令之后会得到如下返回结果:

generic_x86_64:/ $ am start -W -n com.android.settings/com.android.settings.Settings
Starting: Intent { cmp=com.android.settings/.Settings }
Status: ok
Activity: com.android.settings/.Settings
ThisTime: 209
TotalTime: 209
WaitTime: 231
Complete

3、启动流程分析

  下面讲进入正篇,分析Activity启动的源码

// frameworks/base/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
int runStartActivity(PrintWriter pw) throws RemoteException {
    // 首先通过makeIntent函数解析am命令的参数,然后根据参数生成Internet
    Intent intent;
    try {
        intent = makeIntent(UserHandle.USER_CURRENT);
    } catch (URISyntaxException e) {
        throw new RuntimeException(e.getMessage(), e);
    }
	...

    // 创建并初始化ActivityOptions,ActivityOptions中保存着DisplayId,WindowingMode,ActivityType等信息
    ActivityOptions options = null;
    if (mDisplayId != INVALID_DISPLAY) {
        options = ActivityOptions.makeBasic();
        options.setLaunchDisplayId(mDisplayId);
    }
    if (mWindowingMode != WINDOWING_MODE_UNDEFINED) {
        if (options == null) {
            options = ActivityOptions.makeBasic();
        }
        options.setLaunchWindowingMode(mWindowingMode);
    }
    if (mActivityType != ACTIVITY_TYPE_UNDEFINED) {
        if (options == null) {
            options = ActivityOptions.makeBasic();
        }
        options.setLaunchActivityType(mActivityType);
    }
    if (mTaskId != INVALID_TASK_ID) {
        if (options == null) {
            options = ActivityOptions.makeBasic();
        }
        options.setLaunchTaskId(mTaskId);

        if (mIsTaskOverlay) {
            options.setTaskOverlay(true, true /* canResume */);
        }
    }
    if (mIsLockTask) {
        if (options == null) {
            options = ActivityOptions.makeBasic();
        }
        options.setLockTaskEnabled(true);
    }
    
    // 由于设置了-W参数,所以这里mWaitOption = true
    if (mWaitOption) {
    	// mInterface为ActivityManagerService的代理对象,这里调用了AMS的startActivityAndWait函数
        result = mInterface.startActivityAndWait(null, null, intent, mimeType,
              null, null, 0, mStartFlags, profilerInfo,
              options != null ? options.toBundle() : null, mUserId);
        res = result.result;
    } else {
        res = mInterface.startActivityAsUser(null, null, intent, mimeType,
              null, null, 0, mStartFlags, profilerInfo,
              options != null ? options.toBundle() : null, mUserId);
    } 
    // 处理result
    ...

    return 0;
}

  runStartActivity函数首先会解析am命令的参数并创建Intent和ActivityOptions,然后通过Binder调用ActivityManagerService的startActivityAndWait函数

// frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
        Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
        int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
    enforceNotIsolatedCaller("startActivityAndWait");
    userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
            userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
    WaitResult res = new WaitResult();
    // TODO: Switch to user app stacks here.
    // mActivityStartController.obtainStarter会返回ActivityStarter对象
    mActivityStartController.obtainStarter(intent, "startActivityAndWait")
            .setCaller(caller)
            .setCallingPackage(callingPackage)
            .setResolvedType(resolvedType)
            .setResultTo(resultTo)
            .setResultWho(resultWho)
            .setRequestCode(requestCode)
            .setStartFlags(startFlags)
            .setActivityOptions(bOptions)
            .setMayWait(userId)
            .setProfilerInfo(profilerInfo)
            .setWaitResult(res)
            .execute();
    return res;
}

  在startActivityAndWait函数中,首先获取并初始化ActivityStarter对象,然后调用他的execute方法

// frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
int execute() {
    try {
        // TODO(b/64750076): Look into passing request directly to these methods to allow
        // for transactional diffs and preprocessing.
        if (mRequest.mayWait) {
            return startActivityMayWait(mRequest.caller, mRequest.callingUid,
                    mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,
                    mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                    mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
                    mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
                    mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
                    mRequest.inTask, mRequest.reason,
                    mRequest.allowPendingRemoteAnimationRegistryLookup);
        } else {
            return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
                    mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
                    mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                    mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
                    mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
                    mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
                    mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
                    mRequest.outActivity, mRequest.inTask, mRequest.reason,
                    mRequest.allowPendingRemoteAnimationRegistryLookup);
        }
    } finally {
        onExecutionComplete();
    }
}

  这里由于使用了-W参数所以这里调用startActivityMayWait方法,前面都是一些转调用,后面才开始真正的处理流程

3.1 创建ActivityRecord

// frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
private int startActivityMayWait(IApplicationThread caller, int callingUid,
        String callingPackage, Intent intent, String resolvedType,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        IBinder resultTo, String resultWho, int requestCode, int startFlags,
        ProfilerInfo profilerInfo, WaitResult outResult,
        Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
        int userId, TaskRecord inTask, String reason,
        boolean allowPendingRemoteAnimationRegistryLookup) {
    ...
	// 获得调用者的uid和pid
    final int realCallingPid = Binder.getCallingPid();
    final int realCallingUid = Binder.getCallingUid();

    int callingPid;
    if (callingUid >= 0) {
        callingPid = -1;
    } else if (caller == null) {
        callingPid = realCallingPid;
        callingUid = realCallingUid;
    } else {
        callingPid = callingUid = -1;
    }

	// 保存一个Intent的备份
    // Save a copy in case ephemeral needs it
    final Intent ephemeralIntent = new Intent(intent);
    // Don't modify the client's object!
    intent = new Intent(intent);
    ...
    
    // 从PackageManagerService处获取应用信息,PackageManagerService会解析应用的AndroidManifest.xml文件然后把应用信息保存
    ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
            0 /* matchFlags */,computeResolveFilterUid(
            callingUid, realCallingUid, mRequest.filterCallingUid));
       
    if (rInfo == null) {
       ...
    }
    
    // 根据ResolveInfo取得ActivityInfo,ActivityInfo保存着Activity的基本信息
    // Collect information about the target of the Intent.
    ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);

    synchronized (mService) {
    	// 判断Configuration是否发生改变
        final ActivityStack stack = mSupervisor.mFocusedStack;
        stack.mConfigWillChange = globalConfig != null
                && mService.getGlobalConfiguration().diff(globalConfig) != 0;
        if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
                "Starting activity when config will change = " + stack.mConfigWillChange);

        final long origId = Binder.clearCallingIdentity();

        if (aInfo != null && (aInfo.applicationInfo.privateFlags
                & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0 &&
                mService.mHasHeavyWeightFeature) {
            // heavy-weight process处理流程
            ... 
            
        }

        final ActivityRecord[] outRecord = new ActivityRecord[1];
        // 调用startActivity
        int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
                voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
                callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
                ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
                allowPendingRemoteAnimationRegistryLookup);

        Binder.restoreCallingIdentity(origId);

        if (stack.mConfigWillChange) {
            // 如果Configuration发生改变则更新Configuration
            // If the caller also wants to switch to a new configuration,
            // do so now.  This allows a clean switch, as we are waiting
            // for the current activity to pause (so we will not destroy
            // it), and have not yet started the next activity.mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
                    "updateConfiguration()");
            stack.mConfigWillChange = false;
            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
                    "Updating to new configuration after starting activity.");
            mService.updateConfigurationLocked(globalConfig, null, false);
        }

        if (outResult != null) {
       	   // 处理返回结果
           ...
		}
        mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outRecord[0]);
        return res;
    }
}

  这里解释下该函数中几个重要参数:

参数 说明
caller 用于跟调用者进程的ApplicationThread进行通信的binder代理类
callingUid 调用者的uid
callingPackage 调用者的包名
intent 启动Activity时传的参数
resultTo 根据resultTo可以找到调用者的ActivityRecord,用于接收返回结果
startFlags Intent携带的start activity对应的flag
profilerInfo 性能统计有关相关
outResult 用于保存返回结果
globalConfig 以特定的配置启动Activity,例如横屏启动Activity时
options ActivityOptions类型,可以指定Activity的WindowingMode,DisplayID等
userId 用户ID,多用户相关
inTask 指定启动Activity的Task

  继续分析启动流程startActivity

// frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
private int startActivity(......) {

    if (TextUtils.isEmpty(reason)) {
        throw new IllegalArgumentException("Need to specify a reason.");
    }
    mLastStartReason = reason;
    mLastStartActivityTimeMs = System.currentTimeMillis();
    mLastStartActivityRecord[0] = null;
	// 转调用
    mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
            aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
            callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
            options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
            inTask, allowPendingRemoteAnimationRegistryLookup);

    if (outActivity != null) {
        // mLastStartActivityRecord[0] is set in the call to startActivity above.
        outActivity[0] = mLastStartActivityRecord[0];
    }

    return getExternalResult(mLastStartActivityResult);
}

----------------------------------------------------------------------------------------------------------------------------------------------------------
private int startActivity(......) {
    int err = ActivityManager.START_SUCCESS;
    // Pull the optional Ephemeral Installer-only bundle out of the options early.
    final Bundle verificationBundle
            = options != null ? options.popAppVerificationBundle() : null;

    ProcessRecord callerApp = null;
    if (caller != null) {
    // 如果参数中的调用者不为空,则从AMS中找到对应的ProcessRecord,目的是得到调用者的pid和uid
        callerApp = mService.getRecordForAppLocked(caller);
        if (callerApp != null) {
            callingPid = callerApp.pid;
            callingUid = callerApp.info.uid;
        } else {
            Slog.w(TAG, "Unable to find app for caller " + caller
                    + " (pid=" + callingPid + ") when starting: "
                    + intent.toString());
            err = ActivityManager.START_PERMISSION_DENIED;
        }
    }

    ...

    // sourceRecord用于保存父Activity的信息
    ActivityRecord sourceRecord = null;
    // resultRecord用于保存接收启动结果的Activity,对于startActivityForResult才有意义
    ActivityRecord resultRecord = null;
    if (resultTo != null) {
    	// 根据参数resultTo从ActivityStackSupervisor中获取对应的ActivityRecord
        sourceRecord = mSupervisor.isInAnyStackLocked(resultTo);
        if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
                "Will send result to " + resultTo + " " + sourceRecord);
        if (sourceRecord != null) {
            if (requestCode >= 0 && !sourceRecord.finishing) {
                resultRecord = sourceRecord;
            }
        }
    }
	
	// 得到启动Activity使用的标志位
    final int launchFlags = intent.getFlags();

    if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
	    // 处理launchFlags中包含Intent.FLAG_ACTIVITY_FORWARD_RESULT的情况
  		...
    }
	// 错误检查,以及权限检查,这里省略
    ...
    
	// 通过ActivityInfo等信息创建ActivityRecord对象
    ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
            resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
            mSupervisor, checkedOptions, sourceRecord);

    if (outActivity != null) {
        outActivity[0] = r;
    }
	...

    if (mService.mDidAppSwitch) {
    	// 检查调用进程是否有权限切换Activity
        // This is the second allowed switch since we stopped switches,
        // so now just generally allow switches.  Use case: user presses
        // home (switches disabled, switch to home, mDidAppSwitch now true);
        // user taps a home icon (coming from home so allowed, we hit here
        // and now allow anyone to switch again).
        mService.mAppSwitchesAllowedTime = 0;
    } else {
        mService.mDidAppSwitch = true;
    }
	// 处理由于不允许切换Activity时而处于Pending状态的Activity
    mController.doPendingActivityLaunches(false);
	// 调用startActivity
    return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
            true /* doResume */, checkedOptions, inTask, outActivity);
}

startActivity函数很长,但主干比较清晰,只是添加许多条件判断。
从代码来看主要工作包括:

  1. 处理sourceRecord和resultRecord,
    sourceRecord表示发起本次请求的Activity,即父Activity对应的信息;
    resultRecord表示接收处理结果的Activity。
    在一般情况下,sourceRecord和resultRecord应指向同一个Activity;
  2. 创建ActivityRecord,ActivityRecord用于保存Activity的信息,也就是说现在AMS中已经拥有了该Activity的实例,但是该Activity还没有和TaskRecord关联,之后会介绍关联的过程。
  3. 处理app switch
    如果AMS当前禁止app switch,那么AMS会将本次请求保存起来,以待允许app switch时再进行处理。
  4. 调用startActivity继续进行本次请求

3.2 创建TaskRecord 和ActivityStack

// frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
private int startActivity(......) {
    int result = START_CANCELED;
    try {
        mService.mWindowManager.deferSurfaceLayout();
        // 转调用
        result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                startFlags, doResume, options, inTask, outActivity);
    } finally {
        // If we are not able to proceed, disassociate the activity from the task. Leaving an
        // activity in an incomplete state can lead to issues, such as performing operations
        // without a window container.
        final ActivityStack stack = mStartActivity.getStack();
        if (!ActivityManager.isStartResultSuccessful(result) && stack != null) {
            stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,
                    null /* intentResultData */, "startActivity", true /* oomAdj */);
        }
        mService.mWindowManager.continueSurfaceLayout();
    }

    postStartActivityProcessing(r, result, mTargetStack);

    return result;
}

----------------------------------------------------------------------------------------------------------------------------------------------------------
private int startActivityUnchecked(......) {
	//根据参数重新设置ActivityStarter的成员变量
    setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,voiceInteractor);
	// 计算mLaunchFlags, 一般是判断是否需要在mLaunchFlags中加入FLAG_ACTIVITY_NEW_TASK
    computeLaunchingTaskFlags()
    
	// 获得mSourceStack
    computeSourceStack();

    mIntent.setFlags(mLaunchFlags);

	// 判断新Activity是否可以复用之前已经启动的Activity,返回null表示否,一般指定了TaskId的情况下才会出现复用
    ActivityRecord reusedActivity = getReusableIntentActivity();
   
    ....

    if (reusedActivity != null) {
        // 处理Activity复用的情况
        // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but
        // still needs to be a lock task mode violation since the task gets cleared out and
        // the device would otherwise leave the locked task.
         ...

        // 设置待启动Activity的Task
        // If mStartActivity does not have a task associated with it, associate it with the
        // reused activity's task. Do not do so if we're clearing top and resetting for a
        // standard launchMode activity.
        if (mStartActivity.getTask() == null && !clearTopAndResetStandardLaunchMode) {
            mStartActivity.setTask(reusedActivity.getTask());
        }

        if (reusedActivity.getTask().intent == null) {
            // 如果复用Activity之前的Task没有Intent,现在重新设置
            // This task was started because of movement of the activity based on affinity...
            // Now that we are actually launching it, we can assign the base intent.
            reusedActivity.getTask().setIntent(mStartActivity);
        }

        // 以singleTask等方式启动现有Task中的Activity,将会清空该Activity其上的Activity
        // This code path leads to delivering a new intent, we want to make sure we schedule it
        // as the first operation, in case the activity will be resumed as a result of later
        // operations.
        if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
                || isDocumentLaunchesIntoExisting(mLaunchFlags)
                || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
            final TaskRecord task = reusedActivity.getTask();

            // 这里进行清空操作
            // In this situation we want to remove all activities from the task up to the one
            // being started. In most cases this means we are resetting the task to its initial
            // state.
            final ActivityRecord top = task.performClearTaskForReuseLocked(mStartActivity,
                    mLaunchFlags);

            // The above code can remove {@code reusedActivity} from the task, leading to the
            // the {@code ActivityRecord} removing its reference to the {@code TaskRecord}. The
            // task reference is needed in the call below to
            // {@link setTargetStackAndMoveToFrontIfNeeded}.
            if (reusedActivity.getTask() == null) {
                reusedActivity.setTask(task);
            }

            if (top != null) {
                if (top.frontOfTask) {
                    // 设置top activity为待启动的Activity
                    // Activity aliases may mean we use different intents for the top activity,
                    // so make sure the task now has the identity of the new intent.
                    top.getTask().setIntent(mStartActivity);
                }
                // 回调待启动Activity的onNewIntent方法
                deliverNewIntent(top);
            }
        }

        mSupervisor.sendPowerHintForLaunchStartIfNeeded(false /* forceSend */, reusedActivity);
        // 将复用Activity对应的TaskRecord插入到相应的ActivityStack的顶部,并将该ActivityStack移动到前台
        reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity);

        final ActivityRecord outResult =
                outActivity != null && outActivity.length > 0 ? outActivity[0] : null;

        // 处理返回结果
        // When there is a reused activity and the current result is a trampoline activity,
        // set the reused activity as the result.
        if (outResult != null && (outResult.finishing || outResult.noDisplay)) {
            outActivity[0] = reusedActivity;
        }

        if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
            // 该函数会调用到ActivityStackSupervisor的resumeFocusedStackTopActivityLocked函数后面会有介绍
            // We don't need to start a new activity, and the client said not to do anything
            // if that is the case, so this is it!  And for paranoia, make sure we have
            // correctly resumed the top activity.
            resumeTargetStackIfNeeded();
            return START_RETURN_INTENT_TO_CALLER;
        }

        if (reusedActivity != null) {
            // 据复用Activity的信息,修改待加入Task相关的变量
            setTaskFromIntentActivity(reusedActivity);

            if (!mAddingToTask && mReuseTask == null) {
                // We didn't do anything...  but it was needed (a.k.a., client don't use that
                // intent!)  And for paranoia, make sure we have correctly resumed the top activity.
                resumeTargetStackIfNeeded();
                if (outActivity != null && outActivity.length > 0) {
                    outActivity[0] = reusedActivity;
                }

                return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP;
            }
        }
    }

	....
    // 下面的代码会配置Activity的Task和Stack,后面详细分析
    // Should this be considered a new task?
    int result = START_SUCCESS;
    if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
            && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
        newTask = true;
        result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, topStack);1} else if (mSourceRecord != null) {
        result = setTaskFromSourceRecord();
    } else if (mInTask != null) {
        result = setTaskFromInTask();
    } else {
        // This not being started from an existing activity, and not part of a new task...
        // just put it in the top task, though these days this case should never happen.
        setTaskToCurrentTopOrCreateNewTask();
    }
    if (result != START_SUCCESS) {
        return result;
    }

    ....
    // 通知WindowManager准备App切换相关的工作
    mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
            mOptions);		
    if (mDoResume) {
        final ActivityRecord topTaskActivity =
                mStartActivity.getTask().topRunningActivityLocked();
        if (!mTargetStack.isFocusable()
                || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                && mStartActivity != topTaskActivity)) {
            // If the activity is not focusable, we can't resume it, but still would like to
            // make sure it becomes visible as it starts (this will also trigger entry
            // animation). An example of this are PIP activities.
            // Also, we don't want to resume activities in a task that currently has an overlay
            // as the starting activity just needs to be in the visible paused state until the
            // over is removed.
            mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
            // Go ahead and tell window manager to execute app transition for this activity
            // since the app transition will not be triggered through the resume channel.
            mService.mWindowManager.executeAppTransition();
        } else {
            // If the target stack was not previously focusable (previous top running activity
            // on that stack was not visible) then any prior calls to move the stack to the
            // will not update the focused stack.  If starting the new activity now allows the
            // task stack to be focusable, then ensure that we now update the focused stack
            // accordingly.
            if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
                mTargetStack.moveToFront("startActivityUnchecked");
            }
            mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                    mOptions);2}
    } else if (mStartActivity != null) {
        mSupervisor.mRecentTasks.add(mStartActivity.getTask());
    }
    mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);
    mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(), preferredWindowingMode,
            preferredLaunchDisplayId, mTargetStack);

    return START_SUCCESS;
}

  startActivityUnchecked函数最重要的工作就是为待启动的ActivityRecord找到他对应的TaskRecord和ActivityStack,接下来重点介绍TaskRecord和ActivityStack的创建和关联过程(以setTaskFromReuseOrCreateNewTask函数为例)由于代码中分支比较多,所以只分析了其中的一条线,其他分支感兴趣的可以自己看看。

// frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
private int setTaskFromReuseOrCreateNewTask(
        TaskRecord taskToAffiliate, ActivityStack topStack) {
    // 【1.1】获取ActivityStack
    mTargetStack = computeStackFocus(mStartActivity, true, mLaunchFlags, mOptions);

    // Do no move the target stack to front yet, as we might bail if
    // isLockTaskModeViolation fails below.

    if (mReuseTask == null) {
    	// 【1.2】创建TaskRecord
        final TaskRecord task = mTargetStack.createTaskRecord(
                mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId),
                mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
                mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
                mVoiceInteractor, !mLaunchTaskBehind /* toTop */, mStartActivity, mSourceRecord,
                mOptions);
        // 【1.3】将ActivityRecord添加到TaskRecord中
        addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");
        updateBounds(mStartActivity.getTask(), mLaunchParams.mBounds);

        if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
                + " in new task " + mStartActivity.getTask());
    } else {
        addOrReparentStartingActivity(mReuseTask, "setTaskFromReuseOrCreateNewTask");
    }

    if (taskToAffiliate != null) {
        mStartActivity.setTaskToAffiliateWith(taskToAffiliate);
    }

    if (mService.getLockTaskController().isLockTaskModeViolation(mStartActivity.getTask())) {
        Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
        return START_RETURN_LOCK_TASK_MODE_VIOLATION;
    }

    if (mDoResume) {
    	// 【1.4】将ActivityStack移动到顶部
        mTargetStack.moveToFront("reuseOrNewTask");
    }
    return START_SUCCESS;
}

  接下来一步一步进行分析:
  【1.1】获取ActivityStack

// frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
private ActivityStack computeStackFocus(ActivityRecord r, boolean newTask, int launchFlags,
        ActivityOptions aOptions) {
    // 在不指定inTask的情况下这里的task一般为null
    final TaskRecord task = r.getTask();
    ActivityStack stack = getLaunchStack(r, launchFlags, task, aOptions);

    if (stack != null) {
        return stack;
    }
    // 后面处理ActivityStack创建失败的情况
	....
}

  后面的处理暂时先不管先看getLaunchStack函数

// frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
private ActivityStack getLaunchStack(ActivityRecord r, int launchFlags, TaskRecord task,
        ActivityOptions aOptions) {
    // TaskRecord重用的情况这里不考虑
    // We are reusing a task, keep the stack!
    if (mReuseTask != null) {
        return mReuseTask.getStack();
    }

    if (((launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) == 0)
             || mPreferredDisplayId != DEFAULT_DISPLAY) {
        // We don't pass in the default display id into the get launch stack call so it can do a
        // full resolution.
        final int candidateDisplay =
                mPreferredDisplayId != DEFAULT_DISPLAY ? mPreferredDisplayId : INVALID_DISPLAY;
      
        return mSupervisor.getLaunchStack(r, aOptions, task, ON_TOP, candidateDisplay);
    }

 	// 后面处理包含FLAG_ACTIVITY_LAUNCH_ADJACENT的情况
 	....
}

  这里调用了ActivityStackSupervisor的getLaunchStack函数

// frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
<T extends ActivityStack> T getLaunchStack(@Nullable ActivityRecord r,
        @Nullable ActivityOptions options, @Nullable TaskRecord candidateTask, boolean onTop,
        int candidateDisplayId) {
    int taskId = INVALID_TASK_ID;
    int displayId = INVALID_DISPLAY;
    //Rect bounds = null;

    // 从ActivityOptions中获取taskId和displayId,ActivityOptions可以在启动App的时候指定
    // We give preference to the launch preference in activity options.
    if (options != null) {
        taskId = options.getLaunchTaskId();
        displayId = options.getLaunchDisplayId();
        // TODO: Need to work this into the equation...
        //bounds = options.getLaunchBounds();
    }

    // First preference for stack goes to the task Id set in the activity options. Use the stack
    // associated with that if possible.
    if (taskId != INVALID_TASK_ID) {
        // Temporarily set the task id to invalid in case in re-entry.
        options.setLaunchTaskId(INVALID_TASK_ID);
        final TaskRecord task = anyTaskForIdLocked(taskId,
                MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE, options, onTop);
        options.setLaunchTaskId(taskId);
        if (task != null) {
            return task.getStack();
        }
    }

    final int activityType = resolveActivityType(r, options, candidateTask);
    T stack = null;

    // Next preference for stack goes to the display Id set in the activity options or the
    // candidate display.
    if (displayId == INVALID_DISPLAY) {
        displayId = candidateDisplayId;
    }
    if (displayId != INVALID_DISPLAY && canLaunchOnDisplay(r, displayId)) {
        if (r != null) {
            // TODO: This should also take in the windowing mode and activity type into account.
            stack = (T) getValidLaunchStackOnDisplay(displayId, r);
            if (stack != null) {
                return stack;
            }
        }

		 // 根据displayId获取ActivityDisplay对象
        final ActivityDisplay display = getActivityDisplayOrCreateLocked(displayId);
        if (display != null) {
            // 调用ActivityDisplay的getOrCreateStack函数创建ActivityStack
            stack = display.getOrCreateStack(r, options, candidateTask, activityType, onTop);
            if (stack != null) {
                return stack;
            }
        }
    }

    // 后面是无法根据displayId获取对应的ActivityDisplay的情况
    ...
}

  这里根据displayId获取对应的ActivityDisplay对象,ActivityDisplay是屏幕的抽象,用mDisplayId区分不同的屏幕,其中保存着ActivityStack的列表ArrayList mStacks,列表中保存的ActivityStack就是需要在这块屏幕上显示的。

// frameworks/base/services/core/java/com/android/server/am/ActivityDisplay.java
<T extends ActivityStack> T getOrCreateStack(int windowingMode, int activityType,
        boolean onTop) {
    if (!alwaysCreateStack(windowingMode, activityType)) {
        T stack = getStack(windowingMode, activityType);
        if (stack != null) {
            return stack;
        }
    }
    return createStack(windowingMode, activityType, onTop);
}

  调用createStack

// frameworks/base/services/core/java/com/android/server/am/ActivityDisplay.java
<T extends ActivityStack> T createStack(int windowingMode, int activityType, boolean onTop) {

	// 省略特殊处理
	....
    // 获取stackId
    final int stackId = getNextStackId();
    return createStackUnchecked(windowingMode, activityType, stackId, onTop);
}

  获得stackId然后调用createStackUnchecked


// frameworks/base/services/core/java/com/android/server/am/ActivityDisplay.java
<T extends ActivityStack> T createStackUnchecked(int windowingMode, int activityType,
        int stackId, boolean onTop) {
    if (windowingMode == WINDOWING_MODE_PINNED) {
        return (T) new PinnedActivityStack(this, stackId, mSupervisor, onTop);
    }
    return (T) new ActivityStack(
                    this, stackId, mSupervisor, windowingMode, activityType, onTop);
}

  终于找到了ActivityStack创建的位置了,可见ActivityStack是由ActivityDisplay创建的,下面看看ActivityStack的构造函数

// frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
ActivityStack(ActivityDisplay display, int stackId, ActivityStackSupervisor supervisor,
        int windowingMode, int activityType, boolean onTop) {
    mStackSupervisor = supervisor;
    mService = supervisor.mService;
    mHandler = new ActivityStackHandler(mService.mHandler.getLooper());
    mWindowManager = mService.mWindowManager;
    mStackId = stackId;
    mCurrentUser = mService.mUserController.getCurrentUserId();
    mTmpRect2.setEmpty();
    // Set display id before setting activity and window type to make sure it won't affect
    // stacks on a wrong display.
    mDisplayId = display.mDisplayId;
    setActivityType(activityType);
    // 多窗口的windowingMode
    setWindowingMode(windowingMode);
    mWindowContainerController = createStackWindowController(display.mDisplayId, onTop,
            mTmpRect2);
    // 多屏的处理感兴趣的可以自己看看  
    postAddToDisplay(display, mTmpRect2.isEmpty() ? null : mTmpRect2, onTop);
}

  目前为止已经创建了ActivityRecord和ActivityStack还差TaskRecord,接下来回到ActivityStarter的setTaskFromReuseOrCreateNewTask函数继续分析TaskRecord的创建过程
【1.2】TaskRecord创建

// frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        boolean toTop, ActivityRecord activity, ActivityRecord source,
        ActivityOptions options) {
    // 创建TaskRecord
    final TaskRecord task = TaskRecord.create(
            mService, taskId, info, intent, voiceSession, voiceInteractor);
    // add the task to stack first, mTaskPositioner might need the stack association
    // 将TaskRecord插入到ActivityStack的mTaskHistory列表中,如果toTop为true则将该TaskRecord放在mTaskHistory的顶部。这样ActivityStack和TaskRecord就关联起来了
    addTask(task, toTop, "createTaskRecord");
    
    ....
    
    return task;
}

  到这里TaskRecord创建完成,注意这里不单单创建了TaskRecord,还将新建的TaskRecord插入到了ActivityStack中mTaskHistory中,将TaskRecord和ActivityStack关联在了一起。

【1.3】将ActivityRecord添加到TaskRecord中

// frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
private void addOrReparentStartingActivity(TaskRecord parent, String reason) {
	// parent为上面创建的TaskRecord,这里由于未指定inTask,所以mStartActivity.getTask()返回null
    if (mStartActivity.getTask() == null || mStartActivity.getTask() == parent) {
    	 // 调用TaskRecord的addActivityToTop函数讲待启动的Activity插入到TaskRecord中的mActivities的顶部
        parent.addActivityToTop(mStartActivity);
    } else {
        mStartActivity.reparent(parent, parent.mActivities.size() /* top */, reason);
    }
}

  现在我们已经将ActivityRecord,TaskRecord和ActivityStack创建完成,并且建立了他们之间的关系。
【1.4】将ActivityStack移动到顶部

// frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
void moveToFront(String reason, TaskRecord task) {
    if (!isAttached()) {
        return;
    }
	// 获取ActivityDisplay
    final ActivityDisplay display = getDisplay();

    if (inSplitScreenSecondaryWindowingMode()) {
    	// 多窗口
        ...
    }

    if (!isActivityTypeHome() && returnsToHomeStack()) {
    	// 启动Home
        // Make sure the home stack is behind this stack since that is where we should return to
        // when this stack is no longer visible.
        mStackSupervisor.moveHomeStackToFront(reason + " returnToHome");
    }

    display.positionChildAtTop(this);
    // 设置ActivityStackSupervisor的mFocusedStack为当前的Stack
    mStackSupervisor.setFocusStackUnchecked(reason, this);
    if (task != null) {
        insertTaskAtTop(task, null);
        return;
    }
}

  调用display的positionChildAtTop函数

// frameworks/base/services/core/java/com/android/server/am/ActivityDisplay.java
void positionChildAtTop(ActivityStack stack) {
    // 转调用
    positionChildAt(stack, mStacks.size());
}

----------------------------------------------------------------------------------------------------------------------------------------------------------

private void positionChildAt(ActivityStack stack, int position) {
    // TODO: Keep in sync with WindowContainer.positionChildAt(), once we change that to adjust
    //       the position internally, also update the logic here
    mStacks.remove(stack);
    final int insertPosition = getTopInsertPosition(stack, position);
    // 将ActiviStack插入到ActivityDisplay的mStacks列表中
    mStacks.add(insertPosition, stack);
    mWindowContainerController.positionChildAt(stack.getWindowContainerController(),
            insertPosition);
    onStackOrderChanged();
}

  到这里ActivityRecord,TaskRecord,ActivityStack,ActivityDisplay已关联完成,并且ActivityStackSuperVisor中的mTargetStack也更新完成。下面通过一张图片总结一下这个过程

Android9.0 Activity启动流程分析(一)_第4张图片

  1. 调用ActivityDisplay的getOrCreateStack函数创建ActivityStack
  2. 调用ActivityStack的createTaskRecord函数创建TaskRecord,并将TaskRecord保存在mTaskHistory中
  3. 调用ActivityStarter的addOrReparentStartingActivity函数将之前创建的ActivityRecord插入到TaskRecord的顶部
  4. 调用ActivityStack的moveToFront函数将自己插入到ActicityDisplay中的mStacks的顶部,并修改ActivityStackSuperVisor的mTargetStack变量为当前ActivityStack
    最后在AMS中形成上图所示的结构

  回到ActivityStarter的startActivityUnchecked函数继续分析

3.3 创建应用进程

  【2】ActivityStackSupervisor的resumeFocusedStackTopActivityLocked函数

// frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
boolean resumeFocusedStackTopActivityLocked(
        ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {

    if (!readyToResume()) {
        return false;
    }

    if (targetStack != null && isFocusedStack(targetStack)) {
        // 转调用
        return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    }

    final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
    if (r == null || !r.isState(RESUMED)) {
        mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
    } else if (r.isState(RESUMED)) {
        // Kick off any lingering app transitions form the MoveTaskToFront operation.
        mFocusedStack.executeAppTransition(targetOptions);
    }
    return false;
}
----------------------------------------------------------------------------------------------------------------------------------------------------------
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
    if (mStackSupervisor.inResumeTopActivity) {
        // Don't even start recursing.
        return false;
    }

    boolean result = false;
    try {
        // Protect against recursion.
        mStackSupervisor.inResumeTopActivity = true;
        // 转调用
        result = resumeTopActivityInnerLocked(prev, options);

        // When resuming the top activity, it may be necessary to pause the top activity (for
        // example, returning to the lock screen. We suppress the normal pause logic in
        // {@link #resumeTopActivityUncheckedLocked}, since the top activity is resumed at the
        // end. We call the {@link ActivityStackSupervisor#checkReadyForSleepLocked} again here
        // to ensure any necessary pause logic occurs. In the case where the Activity will be
        // shown regardless of the lock screen, the call to
        // {@link ActivityStackSupervisor#checkReadyForSleepLocked} is skipped.
        final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
        if (next == null || !next.canTurnScreenOn()) {
            checkReadyForSleep();
        }
    } finally {
        mStackSupervisor.inResumeTopActivity = false;
    }

    return result;
}
----------------------------------------------------------------------------------------------------------------------------------------------------------
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    if (!mService.mBooting && !mService.mBooted) {
        // Not ready yet!
        return false;
    }

    // 获取TaskRecord的栈顶Activity,如果正常的话这个ActivityRecord为待启动的Activity 
    // Find the next top-most activity to resume in this stack that is not finishing and is
    // focusable. If it is not focusable, we will fall into the case below to resume the
    // top activity in the next focusable task.
    final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);

    final boolean hasRunningActivity = next != null;

    ...

    // 将待启动的Activity从下面几个队列中移除
    // The activity may be waiting for stop, but that is no longer
    // appropriate for it.
    mStackSupervisor.mStoppingActivities.remove(next);
    mStackSupervisor.mGoingToSleepActivities.remove(next);
    next.sleeping = false;
    mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(next);

    if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resuming " + next);

    // 如果系统当前正在中断一个Activity,需要先等待那个Activity pause完毕,之后系统会重新调用resumeTopActivityInnerLocked函数,找到下一个要启动的Activity
    // If we are currently pausing an activity, then don't do anything until that is done.
    if (!mStackSupervisor.allPausedActivitiesComplete()) {
        if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
                "resumeTopActivityLocked: Skip resume: some activity pausing.");
        if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
        return false;
    }

    ...

    boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, false);
    // mResumedActivity指向上一次启动的Activity,也就是当前界面显示的Activity
    if (mResumedActivity != null) {
        // 如果当前界面显示了一个Activity,那么在启动新的Activity之前
        // 必须中断当前的Activity,也就是调用当前Activity的onPause函数
        if (DEBUG_STATES) Slog.d(TAG_STATES,
                "resumeTopActivityLocked: Pausing " + mResumedActivity);
        pausing |= startPausingLocked(userLeaving, false, next, false);
    }
    if (pausing && !resumeWhilePausing) {
        //如果系统正在中断当前启动的Activity,并且未设置FLAG_RESUME_WHILE_PAUSING标签则会  
        //进入该分支,等当前Activity中断完成之后会重新调用resumeTopActivityInnerLocked函数
        if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG_STATES,
                "resumeTopActivityLocked: Skip resume: need to start pausing");
        // At this point we want to put the upcoming activity's process
        // at the top of the LRU list, since we know we will be needing it
        // very soon and it would be a waste to let it get killed if it
        // happens to be sitting towards the end.
        if (next.app != null && next.app.thread != null) {
            // 在中断当前界面的Activity时,调整待启动Activity所在进程的优先级,保证其不被kill
            mService.updateLruProcessLocked(next.app, true, null);
        }
        if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
        if (lastResumed != null) {
            lastResumed.setWillCloseOrEnterPip(true);
        }

        return true;
    } else if (mResumedActivity == next && next.isState(RESUMED)
            && mStackSupervisor.allResumedActivitiesComplete()) {
        // It is possible for the activity to be resumed when we paused back stacks above if the
        // next activity doesn't have to wait for pause to complete.
        // So, nothing else to-do except:
        // Make sure we have executed any pending transitions, since there
        // should be nothing left to do at this point.
        executeAppTransition(options);
        if (DEBUG_STATES) Slog.d(TAG_STATES,
                "resumeTopActivityLocked: Top activity resumed (dontWaitForPause) " + next);
        if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
        return true;
    }

    // 若之前存在未正常结束的Activity,那么要优先结束掉这些Activity
    // If the most recent activity was noHistory but was only stopped rather
    // than stopped+finished because the device went to sleep, we need to make
    // sure to finish it as we're making a new activity topmost.
    if (shouldSleepActivities() && mLastNoHistoryActivity != null &&
            !mLastNoHistoryActivity.finishing) {
        if (DEBUG_STATES) Slog.d(TAG_STATES,
                "no-history finish of " + mLastNoHistoryActivity + " on new resume");
        requestFinishActivityLocked(mLastNoHistoryActivity.appToken, Activity.RESULT_CANCELED,
                null, "resume-no-history", false);
        mLastNoHistoryActivity = null;
    }

	...

    ActivityStack lastStack = mStackSupervisor.getLastStack();
    if (next.app != null && next.app.thread != null) {
        // 如果待启动的Activity已有对应的进程存在,则只需要重启Activity
        ...

    } else {
        // Whoops, need to restart this activity!
        if (!next.hasBeenLaunched) {
            next.hasBeenLaunched = true;
        } else {
            if (SHOW_APP_STARTING_PREVIEW) {
                next.showStartingWindow(null /* prev */, false /* newTask */,
                        false /* taskSwich */);
            }
            if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
        }
        if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
        //如果待启动的Activity进程不存在则调用ActivityStackSupervisor的startSpecificActivityLocked函数,启动整个进程
        mStackSupervisor.startSpecificActivityLocked(next, true, true);
    }

    if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
    return true;
}

  resumeTopActivityInnerLocked函数比较繁琐,但整体来讲应该只有两个比较关键的地方:

  1. 如果mResumedActivity不为空,则需要先暂停这个Activity。mResumedActivity代表当前已经存在于界面的Activity。当需要启动一个新的Activity时,需要先停止当前的Activity。这部分工作由startPausingLocked函数来完成。当前的Activity被中断后,将重新启动新的Activity。
  2. 当mResumedActivity为空时,若待启动的Activity对应的进程已经存在,那么仅需要重新启动该Activity;否则,需要调用ActivityStackSupervisor的startSpecificActivityLocked函数,启动整个进程。
    接下来看startSpecificActivityLocked函数
// frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
void startSpecificActivityLocked(ActivityRecord r,
        boolean andResume, boolean checkConfig) {
    // Is this activity's application already running?
    ProcessRecord app = mService.getProcessRecordLocked(r.processName,
            r.info.applicationInfo.uid, true);

    getLaunchTimeTracker().setLaunchTime(r);

    //如果对应进程已经存在,并向AMS注册过
    if (app != null && app.thread != null) {
        try {
            if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                    || !"android".equals(r.info.packageName)) {
                // Don't add this if it is a platform component that is marked
                // to run in multiple processes, because this is actually
                // part of the framework so doesn't make sense to track as a
                // separate apk in the process.
                app.addPackage(r.info.packageName, r.info.applicationInfo.longVersionCode,
                        mService.mProcessStats);
            }
            
            //通知进程启动目标Activity,该函数在第二篇文章中分析
            realStartActivityLocked(r, app, 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.
    }

    // 调用ActivityManagerService的startProcessLocked函数
    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
            "activity", r.intent.getComponent(), false, false, true);
}

  顺着流程,接下来看AMS的startProcessLocked函数:

//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java	
final ProcessRecord startProcessLocked(String processName,
        ApplicationInfo info, boolean knownToBeDead, int intentFlags,
        String hostingType, ComponentName hostingName, boolean allowWhileBooting,
        boolean isolated, boolean keepIfLarge) {
    // 转调用
    return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
            hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
            null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
            null /* crashHandler */);
}
----------------------------------------------------------------------------------------------------------------------------------------------------------
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
        boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
        boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
        String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
    long startTime = SystemClock.elapsedRealtime();
    // ProcessRecord用来记录进程信息
    ProcessRecord app;
    if (!isolated) {
        // 根据processName和uid寻找是否已经存在processRecord
        app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
        checkTime(startTime, "startProcess: after getProcessRecord");
        // FLAG_FROM_BACKGROUND表示发起这次启动的Task属于后台任务
        // 如果没有设置该标志,那么本次启动请求就是由前台Task触发的
        if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
            //如果一个应用在1分钟内连续崩溃超过两次,AMS就会将其ProcessRecord加入到BadProcesses中      
            //正常情况下,一个应用崩溃后,系统会弹出一个警告框以提醒用户 
            //但是如果一个后台Task启动BadProcess,然后该Process崩溃,由于用户看不到该Process对应的界面, 
            //若弹出一个警告框,用户将觉得奇怪;因此,此处禁止后台Task启动BadProcess

            // If we are in the background, then check to see if this process
            // is bad.  If so, we will just silently fail.
            if (mAppErrors.isBadProcessLocked(info)) {
                if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
                        + "/" + info.processName);
                return null;
            }
        } else {
            //如果用户从界面主动选择启动一个Process,即使该Process是BadProcess,也不能禁止该操作       
            //而且还要清空对应Process的“不良”记录 
            //对比上面的代码,可以看出这其实是一种安全机制,防止不健全的程序不断启动潜在的崩溃组件,但该机制不限制用户行为

            // When the user is explicitly starting a process, then clear its
            // crash count so that we won't make it bad until they see at
            // least one crash dialog again, and make the process good again
            // if it had been bad.
            if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
                    + "/" + info.processName);
            mAppErrors.resetProcessCrashTimeLocked(info);
            if (mAppErrors.isBadProcessLocked(info)) {
                EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
                        UserHandle.getUserId(info.uid), info.uid,
                        info.processName);
                mAppErrors.clearBadProcessLocked(info);
                if (app != null) {
                    app.bad = false;
                }
            }
        }
    } else {
        // If this is an isolated process, it can't re-use an existing process.
        app = null;
    }
   
	 ...

    if (app == null) {
        checkTime(startTime, "startProcess: creating new process record");
        //如果未找到已有的ProcessRecord则需要创建出一个新的
        app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
        if (app == null) {
            Slog.w(TAG, "Failed making new process record for "
                    + processName + "/" + info.uid + " isolated=" + isolated);
            return null;
        }
        app.crashHandler = crashHandler;
        app.isolatedEntryPoint = entryPoint;
        app.isolatedEntryPointArgs = entryPointArgs;
        checkTime(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.versionCode, mProcessStats);
        checkTime(startTime, "startProcess: added package to existing proc");
    }

    // 如果当前系统没有准备好,则将app信息保存在mProcessesOnHold列表中
    // If the system is not ready yet, then hold off on starting this
    // process until it is.
    if (!mProcessesReady
            && !isAllowedWhileBooting(info)
            && !allowWhileBooting) {
        if (!mProcessesOnHold.contains(app)) {
            mProcessesOnHold.add(app);
        }
        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
                "System not ready, putting on hold: " + app);
        checkTime(startTime, "startProcess: returning with proc on hold");
        return app;
    }

    checkTime(startTime, "startProcess: stepping in to startProcess");
    // 调用下一个startProcessLocked函数
    final boolean success = startProcessLocked(app, hostingType, hostingNameStr, abiOverride);
    checkTime(startTime, "startProcess: done starting proc!");
    return success ? app : null;
}

  这段代码主要获取了记录进程的ProcessRecord,接下来看重载的startProcessLocked函数

// frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java	
private final boolean startProcessLocked(ProcessRecord app, String hostingType,
        String hostingNameStr, boolean disableHiddenApiChecks, String abiOverride) {
    if (app.pendingStart) {
        return true;
    }
    long startTime = SystemClock.elapsedRealtime();
    // 启动一个进程
    // 若AMS之前维持着这个进程的pid信息,那么现在需要移除
    if (app.pid > 0 && app.pid != MY_PID) {
        checkTime(startTime, "startProcess: removing from pids map");
        synchronized (mPidsSelfLocked) {
            mPidsSelfLocked.remove(app.pid);
            mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
        }
        checkTime(startTime, "startProcess: done removing from pids map");
        app.setPid(0);
    }

    if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
            "startProcessLocked removing on hold: " + app);
    // mProcessesOnHold用于保存那些在系统还没有准备好就提前请求启动的ProcessRecord
    mProcessesOnHold.remove(app);

    checkTime(startTime, "startProcess: starting to update cpu stats");
    updateCpuStats();
    checkTime(startTime, "startProcess: done updating cpu stats");

    try {
        try {
            //通过PKMS检查待启动进程对应的package是否满足启动条件
            final int userId = UserHandle.getUserId(app.uid);
            AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
        } catch (RemoteException e) {
            throw e.rethrowAsRuntimeException();
        }

        int uid = app.uid;
        int[] gids = null;
        int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
        if (!app.isolated) {
            int[] permGids = null;
            try {
                checkTime(startTime, "startProcess: getting gids from package manager");
                // 通过PKMS得到进程对应的Gid
                final IPackageManager pm = AppGlobals.getPackageManager();
                permGids = pm.getPackageGids(app.info.packageName,
                        MATCH_DEBUG_TRIAGED_MISSING, app.userId);
                StorageManagerInternal storageManagerInternal = LocalServices.getService(
                        StorageManagerInternal.class);
                // 这里应该是判断进程对外部存储设备的访问模式
                mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
                        app.info.packageName);
            } catch (RemoteException e) {
                throw e.rethrowAsRuntimeException();
            }

            // 讲进程的gid信息保存在gids数组中
            /*
             * Add shared application and profile GIDs so applications can share some
             * resources like shared libraries and access user-wide resources
             */
             // 
            if (ArrayUtils.isEmpty(permGids)) {
                gids = new int[3];
            } else {
                gids = new int[permGids.length + 3];
                System.arraycopy(permGids, 0, gids, 3, permGids.length);
            }
            gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
            gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
            gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));

            // Replace any invalid GIDs
            if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
            if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];
        }
        checkTime(startTime, "startProcess: building args");
		 ...

        // ABI表示应用程序二进制接口,ABI精确地定义了你的应用程序及其代码期在运行时如何和系统交互
        String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
        if (requiredAbi == null) {
            requiredAbi = Build.SUPPORTED_ABIS[0];
        }

        String instructionSet = null;
        if (app.info.primaryCpuAbi != null) {
            // 得到对应的指令集
            instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
        }

        app.gids = gids;
        app.requiredAbi = requiredAbi;
        app.instructionSet = instructionSet;

        // the per-user SELinux context must be set
        if (TextUtils.isEmpty(app.info.seInfoUser)) {
            Slog.wtf(TAG, "SELinux tag not defined",
                    new IllegalStateException("SELinux tag not defined for "
                    + app.info.packageName + " (uid " + app.uid + ")"));
        }
        final String seInfo = app.info.seInfo
                + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
        // //指定反射的className
        // Start the process.  It will either succeed and return a result containing
        // the PID of the new process, or else throw a RuntimeException.
        final String entryPoint = "android.app.ActivityThread";

        return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
                runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
                startTime);
    } catch (RuntimeException e) {
        ...
    }
}

  该函数中主要配置了创建进程的一些参数,继续看重载的startProcessLocked函数

// frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java	
private boolean startProcessLocked(String hostingType, String hostingNameStr, String entryPoint,
        ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
        String seInfo, String requiredAbi, String instructionSet, String invokeWith,
        long startTime) {
    // 在保存ProcessRecord中保存进程信息
    app.pendingStart = true;
    app.killedByAm = false;
    app.removed = false;
    app.killed = false;
    final long startSeq = app.startSeq = ++mProcStartSeqCounter;
    app.setStartParams(uid, hostingType, hostingNameStr, seInfo, startTime);
    if (mConstants.FLAG_PROCESS_START_ASYNC) {
        if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,
                "Posting procStart msg for " + app.toShortString());
        mProcStartHandler.post(() -> {
            try {
                synchronized (ActivityManagerService.this) {
                    final String reason = isProcStartValidLocked(app, startSeq);
                    if (reason != null) {
                        Slog.w(TAG_PROCESSES, app + " not valid anymore,"
                                + " don't start process, " + reason);
                        app.pendingStart = false;
                        return;
                    }
                    app.usingWrapper = invokeWith != null
                            || SystemProperties.get("wrap." + app.processName) != null;
                    mPendingStarts.put(startSeq, app);
                }
                final ProcessStartResult startResult = startProcess(app.hostingType, entryPoint,
                        app, app.startUid, gids, runtimeFlags, mountExternal, app.seInfo,
                        requiredAbi, instructionSet, invokeWith, app.startTime);
                synchronized (ActivityManagerService.this) {
                    handleProcessStartedLocked(app, startResult, startSeq);
                }
            } catch (RuntimeException e) {
                synchronized (ActivityManagerService.this) {
                    Slog.e(TAG, "Failure starting process " + app.processName, e);
                    mPendingStarts.remove(startSeq);
                    app.pendingStart = false;
                    forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
                            false, false, true, false, false,
                            UserHandle.getUserId(app.userId), "start failure");
                }
            }
        });
        return true;
    } else {
        try {
            // 调用startProcess函数
            final ProcessStartResult startResult = startProcess(hostingType, entryPoint, app,
                    uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
                    invokeWith, startTime);
            handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
                    startSeq, false);
        } catch (RuntimeException e) {
            Slog.e(TAG, "Failure starting process " + app.processName, e);
            app.pendingStart = false;
            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
                    false, false, true, false, false,
                    UserHandle.getUserId(app.userId), "start failure");
        }
        return app.pid > 0;
    }
}

  继续看startProcess函数

// frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java	
private ProcessStartResult startProcess(String hostingType, String entryPoint,
        ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
        String seInfo, String requiredAbi, String instructionSet, String invokeWith,
        long startTime) {
    try {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
                app.processName);
        checkTime(startTime, "startProcess: asking zygote to start proc");
        final ProcessStartResult startResult;
        if (hostingType.equals("webview_service")) {
            startResult = startWebView(entryPoint,
                    app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                    app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                    app.info.dataDir, null,
                    new String[] {PROC_START_SEQ_IDENT + app.startSeq});
        } else {
            //Process.java的start函数,将通过socket发送消息给zygote
            //zygote将派生出一个子进程,子进程将通过反射调用ActivityThread的main函数 
            //注意此时传递给zygote的参数并没有包含任何与Activity相关的信息
            startResult = Process.start(entryPoint,
                    app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                    app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                    app.info.dataDir, invokeWith,
                    new String[] {PROC_START_SEQ_IDENT + app.startSeq});
        }
        checkTime(startTime, "startProcess: returned from zygote!");
        return startResult;
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    }
}

  至此,startSpecificActivityLocked函数分析完毕,Android系统开始通过zygote创建应用进程。应用进程创建完毕之后会回调ActivityThread的main函数。下面整理一下整个启动流程。
Android9.0 Activity启动流程分析(一)_第5张图片

你可能感兴趣的:(Android,Framework)