Activity的冷启动与生命周期

Activity的冷启动与生命周期

本文基于android12,13 进行分析
activity冷启动的流程如下几个步骤

  1. 应用端调用到AMS开启启动流程,构造出ActivityStarter。
  2. 构造出新的task,并把之前创建的Activity添加至该task。
  3. 服务端执行pause流程,随后拉其新进程。
  4. 应用端完成pasue,随后回调到服务端。
  5. 新进程拉起,执行attach,回调到服务端。
  6. 对需要启动的activity进行resume。

一、应用端调用到AMS开启启动流程,构造出ActivityStarter

该阶段主要做了三件事:
1. 接收应用端启动activit的请求,检查参数是否合法,然后根据参数构造出用来启动activity的ActivityStarter,然后执行该ActivityStater的execute方法.
2. 检查是否有启动activity的权限,没有则终止。然后根据intent构造出新启动Activity对应的ActovotyRecord对象。

如下:

1. 接收应用端启动activity的请求,检查参数是否合法,然后根据参数构造出用来启动activity的ActivityStarter

ActivityTaskManagerService.java
如下在接收都服务端的启动activity请求后,补全参数后,根据参数构造出一个ActivityStater,随后执行他的execute方法:
 @Override
    public int startActivityAsUser(IApplicationThread caller, String callingPackage,
            String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
            String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
            Bundle bOptions, int userId) {
        return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
                resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
                true /*validateIncomingUser*/);
    }

    private int startActivityAsUser(IApplicationThread caller, String callingPackage,
            @Nullable String callingFeatureId, Intent intent, String resolvedType,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
        assertPackageMatchesCallingUid(callingPackage);
        enforceNotIsolatedCaller("startActivityAsUser");
        if (Process.isSdkSandboxUid(Binder.getCallingUid())) {
            SdkSandboxManagerLocal sdkSandboxManagerLocal = LocalManagerRegistry.getManager(
                    SdkSandboxManagerLocal.class);
            if (sdkSandboxManagerLocal == null) {
                throw new IllegalStateException("SdkSandboxManagerLocal not found when starting"
                        + " an activity from an SDK sandbox uid.");
            }
            sdkSandboxManagerLocal.enforceAllowedToStartActivity(intent);
        }

        userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
                Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");

        // TODO: Switch to user app stacks here.
        补全参数后,根据参数构造出一个ActivityStater。并执行ActivityStarter的execute方法
        return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
                .setCaller(caller)
                .setCallingPackage(callingPackage)
                .setCallingFeatureId(callingFeatureId)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(bOptions)
                .setUserId(userId)
                .execute();

    }

2. 检查是否有启动activity的权限,没有则终止

如下经检查是否具有启动activity的权限,没有则终止。随后构造出一个需要启动Activity对应的的ActivityRecord。

ActivityStater.java
    // 正如注释里面所描述的,启动activity的流程在这里开始,这里将开始进行几轮权限检查
 /**
     * Executing activity start request and starts the journey of starting an activity. Here
     * begins with performing several preliminary checks. The normally activity launch flow will
     * go through {@link #startActivityUnchecked} to {@link #startActivityInner}.
     */
    private int executeRequest(Request request) {

     前面进行权限检查的代码非常的长.省略
     
 // app [on install success].
        if (rInfo != null && rInfo.auxiliaryInfo != null) {
            intent = createLaunchIntent(rInfo.auxiliaryInfo, request.ephemeralIntent,
                    callingPackage, callingFeatureId, verificationBundle, resolvedType, userId);
            resolvedType = null;
            callingUid = realCallingUid;
            callingPid = realCallingPid;

            // The ephemeral installer shouldn't get any permission grants
            // intended for the original destination
            intentGrants = null;

            aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
        }
        // TODO (b/187680964) Correcting the caller/pid/uid when start activity from shortcut
        // Pending intent launched from systemui also depends on caller app
        if (callerApp == null && realCallingPid > 0) {
            final WindowProcessController wpc = mService.mProcessMap.getProcess(realCallingPid);
            if (wpc != null) {
                callerApp = wpc;
            }
        }
        //在这里构造出新的ActivityRecord
        final ActivityRecord r = new ActivityRecord.Builder(mService)
                .setCaller(callerApp)
                .setLaunchedFromPid(callingPid)
                .setLaunchedFromUid(callingUid)
                .setLaunchedFromPackage(callingPackage)
                .setLaunchedFromFeature(callingFeatureId)
                .setIntent(intent)
                .setResolvedType(resolvedType)
                .setActivityInfo(aInfo)
                .setConfiguration(mService.getGlobalConfiguration())
                .setResultTo(resultRecord)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setComponentSpecified(request.componentSpecified)
                .setRootVoiceInteraction(voiceSession != null)
                .setActivityOptions(checkedOptions)
                .setSourceRecord(sourceRecord)
                .build();

        mLastStartActivityRecord = r;

        if (r.appTimeTracker == null && sourceRecord != null) {
            // If the caller didn't specify an explicit time tracker, we want to continue
            // tracking under any it has.
            r.appTimeTracker = sourceRecord.appTimeTracker;
        }

        // Only allow app switching to be resumed if activity is not a restricted background
        // activity and target app is not home process, otherwise any background activity
        // started in background task can stop home button protection mode.
        // As the targeted app is not a home process and we don't need to wait for the 2nd
        // activity to be started to resume app switching, we can just enable app switching
        // directly.
        WindowProcessController homeProcess = mService.mHomeProcess;
        boolean isHomeProcess = homeProcess != null
                && aInfo.applicationInfo.uid == homeProcess.mUid;
        if (!restrictedBgActivity && !isHomeProcess) {
            mService.resumeAppSwitches();
        }
        // 权限检查通过,进一步启动
        mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
                request.voiceInteractor, startFlags, true /* doResume */, checkedOptions,
                inTask, inTaskFragment, restrictedBgActivity, intentGrants);

  private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, Task inTask,
            TaskFragment inTaskFragment, boolean restrictedBgActivity,
            NeededUriGrants intentGrants) {
            ......
        try {
            mService.deferWindowLayout();
            Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
            // 在这里进一步启动
            result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, inTaskFragment, restrictedBgActivity,
                    intentGrants);
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
            startedActivityRootTask = handleStartResult(r, options, result, newTransition,
                    remoteTransition);
            mService.continueWindowLayout();
        }
        postStartActivityProcessing(r, result, startedActivityRootTask);

        return result;
    }

二、构造出新的task,并把之前创建的Activity添加至该task

上文中执行了ActivityStater的方法后,会进入到ActivityStater的executeRequest方法中,这个方法非常的长,因为要对传进来启动参数做检查,参数有问题则终止,初次之外还要检查有没有启动目标Activity的权限,没有权限则终止。
在ActivityStater的startActivityInner中主要进行过了如下的步骤:

  1. 计算出需要启动的activity 放到那和Task中,冷启动的话targetTask为null, newTask 为true
  2. 新建的Task,同时把之前创建出来的ActivityRecord添加到新建的task中。
  3. 处理启动窗口和过渡窗口。
  4. 继续进入到RootWindowContainer继续启动流程。
  5. 更新recent栈 的信息。
ActivityStater.java

int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, Task inTask,
            TaskFragment inTaskFragment, boolean restrictedBgActivity,
            NeededUriGrants intentGrants) {
        // 初始化ActivityStater
        setInitialState(r, options, inTask, inTaskFragment, doResume, startFlags, sourceRecord,
                voiceSession, voiceInteractor, restrictedBgActivity);
        ...
        // 从当前已经存在的Task中,根据新建activity的配置信息,找到合适的的task并返回.没有找到合适的就返回null
        final Task reusedTask = getReusableTask();
        ...
        // 计算出需要启动的activity 放到那和Task中,冷启动的话targetTask为null, newTask 为true
        // Compute if there is an existing task that should be used for.
        final Task targetTask = reusedTask != null ? reusedTask : computeTargetTask();
        final boolean newTask = targetTask == null;
        mTargetTask = targetTask;
        ...
        
        // 新建的Task走到这里。
        if (mTargetRootTask == null) {
            mTargetRootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags, targetTask,
                    mOptions);
        }
        if (newTask) {
            final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
                    ? mSourceRecord.getTask() : null;
            // 新建Task的, 这里会把之前创建的ActivityRecord添加到新建的Task中,eventlog打印
            //Starting new activity %s in new task %s
            setNewTask(taskToAffiliate);
        } else if (mAddingToTask) {
            addOrReparentStartingActivity(targetTask, "adding to task");
        }
        // 把新建的task移动到DisplayArea顶部
        if (!mAvoidMoveToFront && mDoResume) {
            mTargetRootTask.getRootTask().moveToFront("reuseOrNewTask", targetTask);
            if (!mTargetRootTask.isTopRootTaskInDisplayArea() && mService.isDreaming()
                    && !dreamStopping) {
                // Launching underneath dream activity (fullscreen, always-on-top). Run the launch-
                // -behind transition so the Activity gets created and starts in visible state.
                mLaunchTaskBehind = true;
                r.mLaunchTaskBehind = true;
            }
        }

        
        ...
        
        if (newTask) {
            // wm_create_task event log打印
            EventLogTags.writeWmCreateTask(mStartActivity.mUserId, startedTask.mTaskId);
        }
        
        ...
        
        // 处理启动窗口,过度动画等、
        mTargetRootTask.startActivityLocked(mStartActivity, topRootTask, newTask, isTaskSwitch,
                mOptions, sourceRecord);
         if (mDoResume) {
            final ActivityRecord topTaskActivity = startedTask.topRunningActivityLocked();
            if (!mTargetRootTask.isTopActivityFocusable()
                    || (topTaskActivity != null && topTaskActivity.isTaskOverlay()
                    && 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.
                // Passing {@code null} as the start parameter ensures all activities are made
                // visible.
                mTargetRootTask.ensureActivitiesVisible(null /* starting */,
                        0 /* configChanges */, !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.
                mTargetRootTask.mDisplayContent.executeAppTransition();
            } else {
                if (mTargetRootTask.isTopActivityFocusable()
                        && !mRootWindowContainer.isTopDisplayFocusedRootTask(mTargetRootTask)) {
                    mTargetRootTask.moveToFront("startActivityInner");
                }
                // 继续启动流程
                mRootWindowContainer.resumeFocusedTasksTopActivities(
                        mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);
            }
        }
        
        ...
        
        // 更新最近任务栈的信息,
        mSupervisor.mRecentTasks.add(startedTask);

三、服务端执行pause流程,随后拉其新进程

1.流程追踪

这里的主要思想是:在启动之前要先对目标屏幕上的已经resume的Activity进行pause,displayArear出发,找到各个叶子节点的Task,对Task中处于resume状态的Activity进行pause处理,顺道新建需要启动actiivty的进程。

进入到RootWindowContainer:

boolean resumeFocusedTasksTopActivities(
            Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions,
            boolean deferPause) {
        if (!mTaskSupervisor.readyToResume()) {
            return false;
        }

        boolean result = false;
        if (targetRootTask != null && (targetRootTask.isTopRootTaskInDisplayArea()
                || getTopDisplayFocusedRootTask() == targetRootTask)) {
            // 继续启动流程,
            // target 带启动的ActiivtyRecord,deferPause:是否延后pause,一般为false
            // 这里的targetRootTask就是我们刚才新建的Task
            result = targetRootTask.resumeTopActivityUncheckedLocked(target, targetOptions,
                    deferPause);
        }
        
        ...
        
    }

接下来会进入到Task的resumeTopActivityUncheckedLocked方法中。

该方法中会遍历,从顶部置Task的叶子节点,直至遍历到叶子节点上才开始进行下一步,否则不断调用Task的resumeTopActivityUncheckedLocked方法进行遍历,这是因为有的Task中的child并不是ActivtyRecord类型,可能是Task类型,只要叶子节点上的Task中的child是ActivityRecord类型。在遍历的过程中会经过需要启动的ActivityRecord所在的Task,也就是刚刚新建的Task,执行该Task的resumeTopActivityInnerLocked();

class Task

 boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options,
            boolean deferPause) {
        if (mInResumeTopActivity) {
            // Don't even start recursing.
            return false;
        }

        boolean someActivityResumed = false;
        try {
            // Protect against recursion.
            mInResumeTopActivity = true;

            if (isLeafTask()) {
                if (isFocusableAndVisible()) {
                    // 当前所在的Task就是我们新建的Task,是叶子节点,则进入到下一步,这里prev是要启动的Activity
                    someActivityResumed = resumeTopActivityInnerLocked(prev, options, deferPause);
                }
            } else {
                int idx = mChildren.size() - 1;
                // 遍历所有子节点,执行resumeTopActivityUncheckedLocked
                while (idx >= 0) {
                    final Task child = (Task) getChildAt(idx--);
                    if (!child.isTopActivityFocusable()) {
                        continue;
                    }
                    if (child.getVisibility(null /* starting */)
                            != TASK_FRAGMENT_VISIBILITY_VISIBLE) {
                        break;
                    }

                    someActivityResumed |= child.resumeTopActivityUncheckedLocked(prev, options,
                            deferPause);
                    // Doing so in order to prevent IndexOOB since hierarchy might changes while
                    // resuming activities, for example dismissing split-screen while starting
                    // non-resizeable activity.
                    if (idx >= mChildren.size()) {
                        idx = mChildren.size() - 1;
                    }
                }
            }
            
            final ActivityRecord next = topRunningActivity(true /* focusableOnly */);
            if (next == null || !next.canTurnScreenOn()) {
                checkReadyForSleep();
            }
        } finally {
            mInResumeTopActivity = false;
        }

        return someActivityResumed;
    }

进入到需要pause的Task:

class Task
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options,
            boolean deferPause) {
        if (!mAtmService.isBooting() && !mAtmService.isBooted()) {
            // Not ready yet!
            return false;
        }
        // 获取该task顶部,处于running状态的task.在需要启动的Task中,topActivity就是要需要启动的Activity
        final ActivityRecord topActivity = topRunningActivity(true /* focusableOnly */);
        if (topActivity == null) {
            // There are no activities left in this task, let's look somewhere else.
            return resumeNextFocusableActivityWhenRootTaskIsEmpty(prev, options);
        }

        final boolean[] resumed = new boolean[1];
        // 获取topActivity的TaskFragment
        final TaskFragment topFragment = topActivity.getTaskFragment();
        // 进一步走到这里,这里的prev 是要启动的ActivityRecord
        resumed[0] = topFragment.resumeTopActivity(prev, options, deferPause);
        forAllLeafTaskFragments(f -> {
            if (topFragment == f) {
                return;
            }
            if (!f.canBeResumed(null /* starting */)) {
                return;
            }
            // 调用TaskFragment的resumeTopActivity方法
            resumed[0] |= f.resumeTopActivity(prev, options, deferPause);
        }, true);
        return resumed[0];
    }

进入到需要启动的ActivityRecord所在的TaskFragment:
在该方法中进行了三个重要的步骤:

  1. 进入到TaskDisplayArea中,从顶部向下开始遍历各个WindowContain节点,找到处于叶子节点的Task,如果该Task中有处于resume的ActivityRecord,进行pause。
  2. 对需要启动的Actiivty拉起一个新进程。
  3. 等待 pause 和 拉起新进程完成,返回。

需要注意的是应用端pause的过程和拉起新进程的是同步进行的,在pauseBackTasks函数中会生成一个pause生命周期的事务然后通过binder发送给需要pause的应用端,随即立刻继续向下执行,执行到AtmService.startProcessAsync()去拉起新进程。而应用端在接收到pause生命周期的事务后开始执行pause。

TaskFragment.java

final boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options,
            boolean deferPause) {
        // next是要启的ActivityRecord
        ActivityRecord next = topRunningActivity(true /* focusableOnly */);
        if (next == null || !next.canResumeByCompat()) {
            return false;
        }
        next.delayedResume = false;

        // If we are currently pausing an activity, then don't do anything until that is done.
        
        // allPausedComplete表明该RootWindowContainer所有已经开始pause的activityRecord是否已经完成pause,RootWindowContainer整个层级数的根节点,即allPausedComplete表明的是整个系统中应已经始paused的activityRecord是否完成pause
        // 当前的系统中虽然有需要被pause的activityRecord,但还并未开始pasue,故该值为 true
        final boolean allPausedComplete = mRootWindowContainer.allPausedActivitiesComplete();
        // allPausedComplete 为true,不会就如该分支
        if (!allPausedComplete) {
            ProtoLog.v(WM_DEBUG_STATES,
                    "resumeTopActivity: Skip resume: some activity pausing.");
            return false;
        }
        
        // TaskDisplayArea节点上挂载着对应屏幕上所有的Task 
        final taskDisplayArea taskDisplayArea = getDisplayArea();
        
        ......
        // taskDisplayArea.pauseBackTasks(next) 执行当前屏幕对应TaskDisplayArea的pauseBackTasks
        // next 为要启动的Activity。当有需要的pasue的ActivityRecord,则pausing为true
        boolean pausing = !deferPause && taskDisplayArea.pauseBackTasks(next);
        if (mResumedActivity != null) {
            ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivity: Pausing %s", mResumedActivity);
            pausing |= startPausing(mTaskSupervisor.mUserLeaving, false /* uiSleeping */,
                    next, "resumeTopActivity");
        }
        // 进入该分支,
        if (pausing) {
            ProtoLog.v(WM_DEBUG_STATES, "resumeTopActivity: 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.attachedToProcess()) {
                next.app.updateProcessInfo(false /* updateServiceConnectionActivities */,
                        true /* activityChange */, false /* updateOomAdj */,
                        false /* addPendingTopUid */);
            // 进入该分支,next需要启动的ActivityRecord,next.isProcessRunning()表示该Activity是否绑定 进程,因为新启动的,则没有绑定进程,则进进入该分支,去拉起进程
            } else if (!next.isProcessRunning()) {
                // Since the start-process is asynchronous, if we already know the process of next
                // activity isn't running, we can start the process earlier to save the time to wait
                // for the current activity to be paused.
                final boolean isTop = this == taskDisplayArea.getFocusedRootTask();
                mAtmService.startProcessAsync(next, false /* knownToBeDead */, isTop,
                        isTop ? HostingRecord.HOSTING_TYPE_NEXT_TOP_ACTIVITY
                                : HostingRecord.HOSTING_TYPE_NEXT_ACTIVITY);
            }
            if (lastResumed != null) {
                lastResumed.setWillCloseOrEnterPip(true);
            }
            // 直接返回,现在系统等pasue和拉起进程结束
            return true;
        } else if (mResumedActivity == next && next.isState(RESUMED) {
            .....
        }
        
        .....
        

之后启动流程一分为二,开始pause和拉起新进程,拉起新进程暂且不表,先继续分析pause过程。接下来继续进入到pauseBackTasks进行分析。
在TaskDisplayArea的pauseBackTasks方法中会遍历该TaskDisplayArea的所有的叶子节点,如果该叶子节点有处于resumed的ActivityRecord,则执行该叶子节点的 startPausing方法。 pauseBackTasks的返回true说明该方法的执行过程中触发了activity的pasue

TaskDisplayArea.java

boolean pauseBackTasks(ActivityRecord resuming) {
        final int[] someActivityPaused = {0};
        // 遍历该TaskDisplayArea的叶子节点
        forAllLeafTasks(leafTask -> {
            // Check if the direct child resumed activity in the leaf task needed to be paused if
            // the leaf task is not a leaf task fragment.
            if (!leafTask.isLeafTaskFragment()) {
                final ActivityRecord top = topRunningActivity();
                final ActivityRecord resumedActivity = leafTask.getResumedActivity();
                if (resumedActivity != null && top.getTaskFragment() != leafTask) {
                    // Pausing the resumed activity because it is occluded by other task fragment.
                    // 继续进行pause流程,resuming为将要启动的ActivityRecord
                    if (leafTask.startPausing(false /* uiSleeping*/, resuming, "pauseBackTasks")) {
                        someActivityPaused[0]++;
                    }
                }
            }

            leafTask.forAllLeafTaskFragments((taskFrag) -> {
                final ActivityRecord resumedActivity = taskFrag.getResumedActivity();
                if (resumedActivity != null && !taskFrag.canBeResumed(resuming)) {
                    if (taskFrag.startPausing(false /* uiSleeping*/, resuming, "pauseBackTasks")) {
                        someActivityPaused[0]++;
                    }
                }
            }, true /* traverseTopToBottom */);
        }, true /* traverseTopToBottom */);
        return someActivityPaused[0] > 0;
    }

如下比较关键,因为接下来开始开始生成ClientTransaction来,然后传递给应用端来执行相关的生命周期变化

TaskFragment.java 

boolean startPausing(boolean userLeaving, boolean uiSleeping, ActivityRecord resuming,
            String reason) {
        //prev =mResumedActivity,即已经resumed的ActivityRecord,需要进行pause
        ActivityRecord prev = mResumedActivity;
        

        if (prev == resuming) {
            Slog.wtf(TAG, "Trying to pause activity that is in process of being resumed");
            return false;
        }

      .....
        // prev是需要进行的paused的ActivityRecord ,自然已经绑定了进程了,进入该分支
        if (prev.attachedToProcess()) {
            if (shouldAutoPip) {
                boolean didAutoPip = mAtmService.enterPictureInPictureMode(
                        prev, prev.pictureInPictureArgs, false /* fromClient */);
                ProtoLog.d(WM_DEBUG_STATES, "Auto-PIP allowed, entering PIP mode "
                        + "directly: %s, didAutoPip: %b", prev, didAutoPip);
            } else {
                // 进入到该流程 继续进行pause
                schedulePauseActivity(prev, userLeaving, pauseImmediately,
                        false /* autoEnteringPip */, reason);
            }
        } else {
            mPausingActivity = null;
            mLastPausedActivity = null;
            mTaskSupervisor.mNoHistoryActivities.remove(prev);
        }
        
        ....
TaskFragment.java 

void schedulePauseActivity(ActivityRecord prev, boolean userLeaving,
            boolean pauseImmediately, boolean autoEnteringPip, String reason) {
        ProtoLog.v(WM_DEBUG_STATES, "Enqueueing pending pause: %s", prev);
        try {
            EventLogTags.writeWmPauseActivity(prev.mUserId, System.identityHashCode(prev),
                    prev.shortComponentName, "userLeaving=" + userLeaving, reason);

            mAtmService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),       // 生成了一个PauseActivityItem
                    prev.token, PauseActivityItem.obtain(prev.finishing, userLeaving,
                            prev.configChangeFlags, pauseImmediately, autoEnteringPip));
            Slog.d("trace_activity_start", " schedulePauseActivity pasueActivity:" + prev + " call:\n" + Arrays.toString(new Exception().getStackTrace()));
        } catch (Exception e) {
            // Ignore exception, if process died other code will cleanup.
            Slog.w(TAG, "Exception thrown during pause", e);
            mPausingActivity = null;
            mLastPausedActivity = null;
            mTaskSupervisor.mNoHistoryActivities.remove(prev);
        }
    }
ClientLifecycleManager.java

void scheduleTransaction(@NonNull IApplicationThread client, @NonNull IBinder activityToken,
            @NonNull ActivityLifecycleItem stateRequest) throws RemoteException {
            // 把刚才生成的PauseActivityItem 和 一众参数封装到 clientTransaction中
        final ClientTransaction clientTransaction = transactionWithState(client, activityToken,
                stateRequest);
        scheduleTransaction(clientTransaction);
    }

2.ATMS通过跨进程的方式使得Activity的生命周期发生转换

上文中在pasue的过程中服务端生成了一个PauseActivityItem,后面把PauseActivityItem封装到ClientTransaction中,随后把这个ClientTransaction发送给应用端执行生命周期转换。

其中个PauseActivityItem派生于ActivityLifecycleItem,类图如下:

  • ActivityLifecycleItem

在这里插入图片描述

可见派生于ActivityLifecycleItem的类有:

  • StartActivityItem
  • ResumeActivityItem
  • PuaseActivityItem
  • StopActivityItem
  • DestroyActivityItem
public abstract class ActivityLifecycleItem extends ActivityTransactionItem {
    
    // 此方法会返回目标的生命周期状态
    @LifecycleState
    public abstract int getTargetState();
}

派生于ActivityLifecycleItem的类实现了getTargetState(),返回值便是目标生命周期状态。

  • BaseClientRequest

同时ActivityLifecycleItem和ClientTransationItem间接或者直接派生于BaseClientRequest,在BaseClientRequest中有三个方法:

public interface BaseClientRequest extends ObjectPoolItem {
    
    // 做执行execute的前置动作
    default void preExecute(ClientTransactionHandler client, IBinder token) {
    }
    // 执行生命周期相关动作
    void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions);
    // 执行execute的收尾动作
    default void postExecute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
    }
}
  • ClientTransaction

在ClientTransaction中有三个字段,分别是:

  • mActivityCallbacks (List )
  • mLifecycleStateRequest (ActivityLifeCycleitem)
  • mClient (保存着应用的一个binder代理)

有两个方法:

  • void preExcute() (在execute之前执行)

  • execute()

  • 从服务端到应用端的总的执行流程
  1. 把ClientTransaction通过mClient发送给应用端
  2. 应用端执行ClientTransaction的preExcute()
    a. 遍历callback执行callback的preExecute()
    b. 执行ActivityLifecycleItem的preExecute()
  3. 应用端执行ClientTransaction的execute()
    a. 遍历callback执行callback的execute()
    b. 遍历callback执行callback的postExecute()
    c. 执行ActivityLifecycleItem的execute()
    d. 执行ActivityLifecycleItem的postExecute()

生命周期转换一般发生在3.a或3.c阶段,而3.b和3.d阶段一般都是当应用的生命周期转换结束后,通过binder执行一些回调到服务端。代工的流程图如下
在这里插入图片描述

ATMS通过跨进程的方式使得Activity的生命周期发生转换的大概流程已经简单介绍了,后面将用pasue和resum举例。

四、应用端完成pasue,随后回调到服务端。

上文可知,服务端在pasue阶段会生成一个包含PasueActivityitem的ClientTransaction,顾该ClientTransaction对象的mLifecycleStateRequest是PasueActivityitem类型,同时在构造ClientTransaction阶段并未给mActivityCallbacks赋值,顾callback为空。
继续跟踪pasue流程。

ClientTransaction经过binder传递给应用端,同时通过scheduleTransaction执行该ClientTransaction

ActivityThread.java

@Override
        public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
            ActivityThread.this.scheduleTransaction(transaction);
        }

如下会会执行ClientTransaction的preExecute(),正如上文所描述,在该方法中会执行callback的preExecute(),和ActivityLifecycleItem的preExecute(),pause的过程中生成ClientTransaction的没有callback,该ClientTransaction中的mLifecycleStateRequest为一个PauseActivityItem,而pasue的preExecute()知识修改了以下进程在虚拟机的状态。

public abstract class ClientTransactionHandler {
    /** Prepare and schedule transaction for execution. */
    void scheduleTransaction(ClientTransaction transaction) {
        // 执行ClientTransaction的preExecute(2.)
        transaction.preExecute(this);
        //将会到ActivityThread的主线称中,调用ClientTransaction的execute()
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }
}

接下来会到TransactionExecutor继续执行ClientTransaction的相关方法,如下:

  1. 执行callback的execute()和postExecute()
  2. 执行ActivityLifecycleItem的execute()和postExecute()。
    因为callback不存在,所以只关注2.执行ActivityLifecycleItem
TransactionExecutor.java

public void execute(ClientTransaction transaction) {
       
       ....
       
        if (DEBUG_RESOLVER) Slog.d(TAG, transactionToString(transaction, mTransactionHandler));
        // 遍历callback执行callback的execute()
        // 遍历callback执行callback的postExecute()
        executeCallbacks(transaction);
        // 执行ActivityLifecycleItem的execute()
        // 执行ActivityLifecycleItem的postExecute()
        executeLifecycleState(transaction);
        mPendingActions.clear();
        
        ....
    }
private void executeLifecycleState(ClientTransaction transaction) {
        // 获取ClientTransaction中的ActivityLifecycleItem
        final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
        if (lifecycleItem == null) {
            // No lifecycle request, return early.
            return;
        }

        final IBinder token = transaction.getActivityToken();
        final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
        if (DEBUG_RESOLVER) {
            Slog.d(TAG, tId(transaction) + "Resolving lifecycle state: "
                    + lifecycleItem + " for activity: "
                    + getShortActivityName(token, mTransactionHandler));
        }

        if (r == null) {
            // Ignore requests for non-existent client records for now.
            return;
        }

        // Cycle to the state right before the final requested state.
        // 计算出当前状态到目标状态的路经,然后依次完成生命周期状态转换,pause不走该流程
        cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */, transaction);

        // Execute the final transition with proper parameters.
        // 执行lifecycleItem的execute 完成 从onResume到onPause的转换
        lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
        // 执行 lifecycleItem.postExecute 进行pause的一些收尾工作,然后会回调到服务端,告诉服务端该Activity已经完成paused
        lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
    }

如上,在executeLifecycleState主要作了三件事:

  1. 通过cycleToPath()
    a. 计算出当前状态到目标状态的路径
    b. 根据计算出的路径依次执行路径上的生命周期的回调
    举个例子:当前状态 create, 目标状态 resume, 那当前的状态到目标状态的路径为 [start,resume],所以依次调用目标activity的onStart()和onResume()方法。
    回到咱们的pause流程,当前的状态是resume,目标状态时pause,故路径为[pause],但是代码中cycleToPath()的excludeLastState=true,所以就会跳过最后一个状态,路径列表移除最后一个状态,故路径列表:[pause],移除最后一个就变成空列表,pasue流程在该函数中不会执行相关生命周期回调。
    可见:cycleToPath()是一个很重要的过程,故可以这样总结:
  • 从服务端到应用端的总的执行流程
  1. 把ClientTransaction通过mClient发送给应用端

  2. 应用端执行ClientTransaction的preExcute()
    a. 遍历callback执行callback的preExecute()
    b. 执行ActivityLifecycleItem的preExecute()

  3. 应用端执行ClientTransaction的execute()
    a. 遍历callback执行callback的execute()
    b. 遍历callback执行callback的postExecute()
    c. cycleToPath()
    d. 执行ActivityLifecycleItem的execute()
    e. 执行ActivityLifecycleItem的postExecute()

  4. lifecycleItem.execute(),即执行PauseActivityItem的execute,这个方法中会调用到目标Activity的onPause()方法,如下:

PauseActivityItem.java

@Override
    public void execute(ClientTransactionHandler client, ActivityClientRecord r,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
        // r目标的Activity,接下来会调用到Activity的onPaused方法
        client.handlePauseActivity(r, mFinished, mUserLeaving, mConfigChanges, mAutoEnteringPip,
                pendingActions, "PAUSE_ACTIVITY_ITEM");
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }
  1. 执行到该方法,就意味这目标Activity的onPause方法已经得到执行,接下来就要向服务端汇报已经完成了pasue:
PauseActivityItem.java

   @Override
    public void postExecute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        if (mDontReport) {
            return;
        }
        // TODO(lifecycler): Use interface callback instead of actual implementation.
        // 这里
        ActivityClient.getInstance().activityPaused(token);
    }

如下在activityPaused方法中将通过binder调用到服务端的ActivityClientController的activityPaused方法,进而向服务端汇,除此之外还可以看到 activityStopped,activityDestroyed之类的方法,这些方法的作用和activityPaused类似。

public class ActivityClient {
    /** Reports {@link Activity#onResume()} is done. */
    public void activityResumed(IBinder token, boolean handleSplashScreenExit) {
        ....
    }
    
    /** Reports {@link Activity#onPause()} is done. */
    public void activityPaused(IBinder token) {
        try {
        // 会通过binder调用到服务端的ActivityClientController的activityPaused方法
            getActivityClientController().activityPaused(token);
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        }
    }

    public void activityStopped(IBinder token, Bundle state, PersistableBundle persistentState,
            CharSequence description) {
        .....
    }

    public void activityDestroyed(IBinder token) {
        .....
    }
    ....
}

接下来,流程回到了服务端,如下:

  1. 根据应用端的传过来的token找出刚才已经完成paused的Activity对应的ActivityRecord。
  2. 执行AtivityRecoed的activityPaused()
ActivityClientController.java

class ActivityClientController extends IActivityClientController.Stub {
    ActivityClientController(ActivityTaskManagerService service) {
        mService = service;
        mGlobalLock = service.mGlobalLock;
        mTaskSupervisor = service.mTaskSupervisor;
        mContext = service.mContext;
    }

    @Override
    public void activityResumed(IBinder token, boolean handleSplashScreenExit) {
        ......
    }

    @Override
    public void activityTopResumedStateLost() {
        ......
    }

    @Override
    public void activityPaused(IBinder token) {
        final long origId = Binder.clearCallingIdentity();
        synchronized (mGlobalLock) {
            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "activityPaused");
            // 根据应用端的传过来的token找出刚才已经完成paused的Activity对应的ActivityRecord
            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
            if (r != null) {
                // pause
                // 根据ActivityRecoed的activityPaused
                r.activityPaused(false);
            }
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
        }
        Binder.restoreCallingIdentity(origId);
    }

    @Override
    public void activityStopped(IBinder token, Bundle icicle, PersistableBundle persistentState,
            CharSequence description) {
        ......
    }

    @Override
    public void activityDestroyed(IBinder token) {
        ....
    }
}

如下将会进一步去resume

void activityPaused(boolean timeout) {
        ProtoLog.v(WM_DEBUG_STATES, "Activity paused: token=%s, timeout=%b", token,
                timeout);

        final TaskFragment taskFragment = getTaskFragment();
        if (taskFragment != null) {
            removePauseTimeout();

            final ActivityRecord pausingActivity = taskFragment.getPausingActivity();
            if (pausingActivity == this) {
                ProtoLog.v(WM_DEBUG_STATES, "Moving to PAUSED: %s %s", this,
                        (timeout ? "(due to timeout)" : " (pause complete)"));
                mAtmService.deferWindowLayout();
                try {
                    // 调用刚才已经pauseactivity对应的TaskFragment的completePause,
                    // 注意这里第一个参数resumeNext为true,这就意味着接下里要去resume Activity了
                    taskFragment.completePause(true /* resumeNext */, null /* resumingActivity */);
                } finally {
                    mAtmService.continueWindowLayout();
                }
                return;
            } else {
               .....
            }
        }
        .....
    }

如下主要完成两件事:

  1. 通过RootWindowContainer.resumeFocusedTasksTopActivities(),服务端resume需要启动的Activity
  2. 通过RootWindowContainer.ensureActivitiesVisible(),将会把之前paused的ActivityRecord添加到stoping列表中,为后续的stop的流程做准备(stop流程后续会介绍)

需要注意的是RootWindowContainer.resumeFocusedTasksTopActivities()这个方法之前进入过。在三.1, 该有一点需要注意的是,在调用mRootWindowContainer.resumeFocusedTasksTopActivities(topRootTask, prev, null /* targetOptions */);的时候传递的第一个参数是topRootTask,topRootTask即为当前在最顶部的Task,因为在前面的流程中,新建task的过程中会把新建的Task移动到最顶部,故topRootTask就为新建的那个Task

@VisibleForTesting
    void completePause(boolean resumeNext, ActivityRecord resuming) {
        // 这里的mPausingActivity就是我们刚才pause的ActivityRecord
        ActivityRecord prev = mPausingActivity;
        .....
        
        // pause的流程已经完成把mPausingActivity置为null
        mPausingActivity = null
        
        //  准备去resume下一个activity
        if (resumeNext) {
            final Task topRootTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
            if (topRootTask != null && !topRootTask.shouldSleepOrShutDownActivities()) {
                // 可以看到,又看到我们熟悉的地方
                mRootWindowContainer.resumeFocusedTasksTopActivities(topRootTask, prev,
                        null /* targetOptions */);
            } else {
                // checkReadyForSleep();
                final ActivityRecord top =
                        topRootTask != null ? topRootTask.topRunningActivity() : null;
                if (top == null || (prev != null && top != prev)) {
                    // If there are no more activities available to run, do resume anyway to start
                    // something. Also if the top activity on the root task is not the just paused
                    // activity, we need to go ahead and resume it to ensure we complete an
                    // in-flight app switch.
                    mRootWindowContainer.resumeFocusedTasksTopActivities();
                }
            }
        }

        if (prev != null) {
            prev.resumeKeyDispatchingLocked();
        }

        // 在这里会把paused的activity添加到Stopping列表中
        mRootWindowContainer.ensureActivitiesVisible(resuming, 0, !PRESERVE_WINDOWS);

        // Notify when the task stack has changed, but only if visibilities changed (not just
        // focus). Also if there is an active root pinned task - we always want to notify it about
        // task stack changes, because its positioning may depend on it.
        if (mTaskSupervisor.mAppVisibilitiesChangedSinceLastPause
                || (getDisplayArea() != null && getDisplayArea().hasPinnedTask())) {
            mAtmService.getTaskChangeNotificationController().notifyTaskStackChanged();
            mTaskSupervisor.mAppVisibilitiesChangedSinceLastPause = false;
        }
    }

接下来的调用流程和三.1一样,就不在细致分析,经过一系列调用,来到了新建Task的父类TaskFragment的resumeTopActivity()方法如下:

TaskFragment.java

    final boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options,
            boolean deferPause) {
        // 在我之前新建的Task中,topRunningActivity 即为新建的ActivtyRecord
        ActivityRecord next = topRunningActivity(true /* focusableOnly */);
        if (next == null || !next.canResumeByCompat()) {
            return false;
        }
       
        // 经过刚才的一轮pasue,已经没有处于pausing状态的ActivirtyReord,故allPausedComplete为ture
        final boolean allPausedComplete = mRootWindowContainer.allPausedActivitiesComplete();
        // 不进入
        if (!allPausedComplete) {
            ProtoLog.v(WM_DEBUG_STATES,
                    "resumeTopActivity: Skip resume: some activity pausing.");
            return false;
        }

        .......

       
`       // 所有的Actiity都pause完成了,故pausing为false
        boolean pausing = !deferPause && taskDisplayArea.pauseBackTasks(next);
        if (mResumedActivity != null) {
            ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivity: Pausing %s", mResumedActivity);
            pausing |= startPausing(mTaskSupervisor.mUserLeaving, false /* uiSleeping */,
                    next, "resumeTopActivity");
        }
        // 不进入
        if (pausing) {
            ....
            return true;
        } else if (mResumedActivity == next && next.isState(RESUMED)
            .....
        }

        // 这里的next的为要启动的Activity,一般情况下,拉起新的进程并attach到服务端的过程比paused的过程慢,假如进程还没完全启动,所以next.attachedToProcess() =false
        if (next.attachedToProcess()) {
            ....
        } else {
            // Whoops, need to restart this activity!
            if (!next.hasBeenLaunched) {
                next.hasBeenLaunched = true;
            } else {
                if (SHOW_APP_STARTING_PREVIEW) {
                    next.showStartingWindow(false /* taskSwich */);
                }
                if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
            }
            ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivity: Restarting %s", next);
            // 进一步到这里,需要注意的是 参数为之前新建的ActivtyRecord
            mTaskSupervisor.startSpecificActivity(next, true, true);
        }

        return true;
    }

如下会获取之前新建ActivityReocrd的WindowProcessController,因为ActivityRecord的进程还没有完全启动,所以wpc == null,随后流程终止,需要 依靠新启动的应用的进程完全启动后来进一步触发resume流程(当然如果进程启动的比pasue的快的话会进入到realStartActivityLocked去正式开始resume)

ActivityTaskSupervisor.java

void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
        // 获取新建ActivityRecord的 WindowProcessController,因为进程为完全启动这里的 WindowProcessController == null
        final WindowProcessController wpc =
                mService.getProcessController(r.processName, r.info.applicationInfo.uid);

        boolean knownToBeDead = false;
        // wpc 为null,流程终止
        if (wpc != null && wpc.hasThread()) {
            try {
                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;
            // Remove the process record so it won't be considered as alive.
            mService.mProcessNames.remove(wpc.mName, wpc.mUid);
            mService.mProcessMap.remove(wpc.getPid());
        }

        r.notifyUnknownVisibilityLaunchedForKeyguardTransition();
        ......

五、新进程拉起,执行attach,回调到服务端

上文中提到过,在服务端发起pause的阶段。同时会去拉起新启动应用的进程,具体启动新进程的流程并不是本文的重点,重点关注进程启动做了什么:
在进程启动后,会通过反射构造出ActivityThread对象,随后又会通过反射调用ActivityThread的main()方法。

1. 构造出新应用进程的ActivityThread,随后调用AMS的attachApplication的方法:

ActivityThread.java

 public static void main(String[] args) {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
        .....
        // 创建出ActivityThread对象
        ActivityThread thread = new ActivityThread();
        执行ActivityThread的attach方法
        thread.attach(false, startSeq);

        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }

        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }

        // End of event ActivityThreadMain.
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
    
    
private void attach(boolean system, long startSeq) {
        sCurrentActivityThread = this;
        mConfigurationController = new ConfigurationController(this);
        mSystemThread = system;
        if (!system) {
            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                    UserHandle.myUserId());
            RuntimeInit.setApplicationObject(mAppThread.asBinder());
            // 获取AMS的代理,执行attachApplication方法
            final IActivityManager mgr = ActivityManager.getService();
            try {
                mgr.attachApplication(mAppThread, startSeq);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
            ....
        }
 .....   
}        
ActivityManagerService.java

@Override
    public final void attachApplication(IApplicationThread thread, long startSeq) {
        if (thread == null) {
            throw new SecurityException("Invalid application interface");
        }
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final int callingUid = Binder.getCallingUid();
            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid, callingUid, startSeq);
            Binder.restoreCallingIdentity(origId);
        }
    }
    

 private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
            int pid, int callingUid, long startSeq) {
        .....
        try {
            // 注册app进程死亡通知处理机制,也就是创建监听app死亡的对象
            // App进程死亡后,会调用AppDeathRecipient.binderDied()方法
            AppDeathRecipient adr = new AppDeathRecipient(
                    app, pid, thread);
            thread.asBinder().linkToDeath(adr, 0);
            app.setDeathRecipient(adr);
        } catch (RemoteException e) {
            app.resetPackageList(mProcessStats);
            mProcessList.startProcessLocked(app,
                    new HostingRecord(HostingRecord.HOSTING_TYPE_LINK_FAIL, processName),
                    ZYGOTE_POLICY_FLAG_EMPTY);
            return false;
        }
        
        // 接下来又会通过bindApplication回到应用进程,对Application做一些初始化
        thread.bindApplication(processName, appInfo,
                        app.sdkSandboxClientAppVolumeUuid, app.sdkSandboxClientAppPackage,
                        providerList, null, profilerInfo, null, null, null, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.isPersistent(),
                        new Configuration(app.getWindowProcessController().getConfiguration()),
                        app.getCompat(), getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial, autofillOptions, contentCaptureOptions,
                        app.getDisabledCompatChanges(), serializedSystemFontMap,
                        app.getStartElapsedTime(), app.getStartUptime());
                        
        .....
        
        if (normalMode) {
            try {
                didSomething =
                // 进一步去触发resume
                mAtmInternal.attachApplication(app.getWindowProcessController());
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }
    }
ActivityTaskManagerService.java

@HotPath(caller = HotPath.PROCESS_CHANGE)
        @Override
        public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
            synchronized (mGlobalLockWithoutBoost) {
                if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
                    Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "attachApplication:" + wpc.mName);
                }
                try {
                    return mRootWindowContainer.attachApplication(wpc);
                } finally {
                    Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
                }
            }
        }
boolean attachApplication(WindowProcessController app) throws RemoteException {
        try {
            return mAttachApplicationHelper.process(app);
        } finally {
            mAttachApplicationHelper.reset();
        }
    }
AttachApplicationHelper

@Override
        public boolean test(ActivityRecord r) {
            if (r.finishing || !r.showToCurrentUser() || !r.visibleIgnoringKeyguard
                    || r.app != null || mApp.mUid != r.info.applicationInfo.uid
                    || !mApp.mName.equals(r.processName)) {
                return false;
            }

            try {
                //
                if (mTaskSupervisor.realStartActivityLocked(r, mApp,
                        mTop == r && r.getTask().canBeResumed(r) /* andResume */,
                        true /* checkConfig */)) {
                    mHasActivityStarted = true;
                }
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception in new application when starting activity " + mTop, e);
                mRemoteException = e;
                return true;
            }
            return false;
        }

如下又到了 realStartActivityLocked(),和之前pause流程的后半段的终点一样:
主要做了三件事:

  1. 判断了有没有完成了pause
  2. 生成ClientTransaction
  3. 把生成ClientTransaction通过binder下发给应用端
1. 判断了有没有完成了pause

在realStartActivityLocked方法中开始阶段判断了有没有完成了pause,没有则终止。回忆之前pause的后半段进入到realStartActivityLocked之前会判断新的Activity有没有新进程,没有则不进入。
进一步总结一下:在启动activity的过程中流程会一分为2同时进行:

1.进行pasue,完成后汇报至服务端,检查进程是否拉起,拉起则执行realStartActivityLocked。2. 去拉起新进程,进程运行后汇报到服务端,检查pasue是否已经完成,完成则执行realStartActivityLocked。

故启动过程中realStartActivityLocked的执行条件是 pasue完成 和 启动新进程完成。

2. 生成ClientTransaction

生成ClientTransaction并给ClientTransaction添加了一个类型为LaunchActivityItem的callback和类型为ResumeActivityItem的LifecycleStateRequest。

3. 把生成ClientTransaction通过binder下发给应用端

随后应用端将会执行ClientTransaction对生命周期进行转换

 boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
            boolean andResume, boolean checkConfig) throws RemoteException {
        // 判断是不是所有的activitypaused,如果有 就不往下执行
        if (!mRootWindowContainer.allPausedActivitiesComplete()) {
            // While there are activities pausing we skipping starting any new activities until
            // pauses are complete. NOTE: that we also do this for activities that are starting in
            // the paused state because they will first be resumed then paused on the client side.
            ProtoLog.v(WM_DEBUG_STATES,
                    "realStartActivityLocked: Skipping start of r=%s some activities pausing...",
                    r);
            return false;
        }

        ......
        
        // 在这里生成一个 clientTransaction 新启动的应用下发生命周期转换的请求了
        final ClientTransaction clientTransaction = ClientTransaction.obtain(
                        proc.getThread(), r.token);

                final boolean isTransitionForward = r.isTransitionForward();
                // 生成生命周期事务
                final IBinder fragmentToken = r.getTaskFragment().getFragmentToken();
                // 给clientTransaction添加了一个类型为 LaunchActivityItem的callback
                clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                        System.identityHashCode(r), r.info,
                        // TODO: Have this take the merged configuration instead of separate global
                        // and override configs.
                        mergedConfiguration.getGlobalConfiguration(),
                        mergedConfiguration.getOverrideConfiguration(), r.compat,
                        r.getFilteredReferrer(r.launchedFromPackage), task.voiceInteractor,
                        proc.getReportedProcState(), r.getSavedState(), r.getPersistentSavedState(),
                        results, newIntents, r.takeOptions(), isTransitionForward,
                        proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController,
                        r.shareableActivityToken, r.getLaunchedFromBubble(), fragmentToken));

                // Set desired final state.
                final ActivityLifecycleItem lifecycleItem;
                if (andResume) {
                    lifecycleItem = ResumeActivityItem.obtain(isTransitionForward);
                } else {
                    lifecycleItem = PauseActivityItem.obtain();
                }
                // 给clientTransaction添加了一个类型为ResumeActivityItem的LifecycleStateRequest
                clientTransaction.setLifecycleStateRequest(lifecycleItem);

                // Schedule transaction.
                // 把clientTransaction下发给新启动的
                mService.getLifecycleManager().scheduleTransaction(clientTransaction);

六、对需要启动的activity进行resum

clientTransaction经过binder来到了应用,接下来应用端将会处理这个clientTransaction。

这次从服务端中传递来的clientTransaction除了有这次从服务端中传递来的clientTransaction除了有callback之外还有行ActivityLifecycleItem之外还有行callback。
在上文梳理的pasue的过程中总结了应用端的对clientTransaction的处理过程,如下:

  • 从服务端到应用端的总的执行流程
  1. 把ClientTransaction通过mClient发送给应用端
  2. 应用端执行ClientTransaction的preExcute()
    a. 遍历callback执行callback的preExecute()
    b. 执行ActivityLifecycleItem的preExecute()
  3. 应用端执行ClientTransaction的execute()
    a. 遍历callback执行callback的execute()
    b. 遍历callback执行callback的postExecute()
    c. cycleToPath()
    d. 执行ActivityLifecycleItem的execute()
    e. 执行ActivityLifecycleItem的postExecute()

对于在这次传递来的ClientTransaction,和生命周期相关的是 cycleToPath(),和 ResumeActivityItem的execute()和postExecute()

  1. 执行cycleToPath()
  2. 执行ResumeActivityItem的execute()
  3. 执行ResumeActivityItem的postExecute()

1. 执行cycleToPath()

执行cycleToPath的excludeLastState为true,所以生成的生命周期路径为 [create, start]
如下:

TransactionExecutor.java

private void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState,
            ClientTransaction transaction) {
        final int start = r.getLifecycleState();
        if (DEBUG_RESOLVER) {
            Slog.d(TAG, tId(transaction) + "Cycle activity: "
                    + getShortActivityName(r.token, mTransactionHandler)
                    + " from: " + getStateName(start) + " to: " + getStateName(finish)
                    + " excludeLastState: " + excludeLastState);
        }
        // 计算出当前生命周期状态到目标生命周期状态的前一个的路径
        final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
        // 按照生成的路径,执行生命周期转换
        performLifecycleSequence(r, path, transaction);
    }

如下就是遍历path,执行生命周期转变的过程。根据path,将会执行handleLaunchActivity和handleStartActivity

TransactionExecutor.java


private void performLifecycleSequence(ActivityClientRecord r, IntArray path,
            ClientTransaction transaction) {
        final int size = path.size();
        for (int i = 0, state; i < size; i++) {
            state = path.get(i);
            if (DEBUG_RESOLVER) {
                Slog.d(TAG, tId(transaction) + "Transitioning activity: "
                        + getShortActivityName(r.token, mTransactionHandler)
                        + " to state: " + getStateName(state));
            }
            switch (state) {
                // 执行onCreate
                case ON_CREATE:
                    mTransactionHandler.handleLaunchActivity(r, mPendingActions,
                            null /* customIntent */);
                    break;
                // 执行onStart
                case ON_START:
                    mTransactionHandler.handleStartActivity(r, mPendingActions,
                            null /* activityOptions */);
                    break;
                case ON_RESUME:
                    mTransactionHandler.handleResumeActivity(r, false /* finalStateRequest */,
                            r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
                    break;
                case ON_PAUSE:
                    mTransactionHandler.handlePauseActivity(r, false /* finished */,
                            false /* userLeaving */, 0 /* configChanges */, mPendingActions,
                            "LIFECYCLER_PAUSE_ACTIVITY");
                    break;
                case ON_STOP:
                    mTransactionHandler.handleStopActivity(r, 0 /* configChanges */,
                            mPendingActions, false /* finalStateRequest */,
                            "LIFECYCLER_STOP_ACTIVITY");
                    break;
                case ON_DESTROY:
                    mTransactionHandler.handleDestroyActivity(r, false /* finishing */,
                            0 /* configChanges */, false /* getNonConfigInstance */,
                            "performLifecycleSequence. cycling to:" + path.get(size - 1));
                    break;
                case ON_RESTART:
                    mTransactionHandler.performRestartActivity(r, false /* start */);
                    break;
                default:
                    throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
            }
        }
    }

1.调用Activity的onCreate方法

构造出要启动的Activity对象,随后调用该Activity的onCreate方法:


@Override
    public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) {
        ....
        // 构造出了目标Activity,并会调用Activity的onCreate方法
        final Activity a = performLaunchActivity(r, customIntent);
        
        ....
    }
    
    
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    
        .....
        
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            // 创建出需要启动的Activity对象
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess(isProtectedComponent(r.activityInfo),
                    appContext.getAttributionSource());
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to instantiate activity " + component
                    + ": " + e.toString(), e);
            }
        }

                // 调用Activity的OnCreate方法
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
            .....

        return activity;
    }

2.调用Activity的onStart方法


@Override
    public void handleStartActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, ActivityOptions activityOptions) {
        final Activity activity = r.activity;
        
        .....
        // 调用对应Activity的onstart方法
        // Start 
        activity.performStart("handleStartActivity");
        r.setState(ON_START);

       .....
        // 更新可见性
        updateVisibility(r, true /* show */);
        mSomeActivitiesChanged = true;
    }

2.执行ResumeActivityItem的execute()

接下来会正式的调用到 ActivityRecord的onResume方法:

ResumeActivityItem.java

@Override
    public void execute(ClientTransactionHandler client, ActivityClientRecord r,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
        client.handleResumeActivity(r, true /* finalStateRequest */, mIsForward,
                "RESUME_ACTIVITY");
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

如下performResumeActivity方法最终会调用到对应Activity的onResume方法。这里只描述onresme的调用流程,实际上activity的resume过程做了很多事情,还是比较复杂的。

ActivityThread.java

 @Override
    public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
            boolean isForward, String reason) {
    
        // 调用目标Activity的onRsume方法
        if (!performResumeActivity(r, finalStateRequest, reason)) {
            return;
        }
        ......
    }

3.执行ResumeActivityItem的postExecute()

以上流程执行完毕后通过ResumeActivityItem的postExecute()方法通知到服务端:

ResumeActivityItem.java

@Override
    public void postExecute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        // TODO(lifecycler): Use interface callback instead of actual implementation.
        ActivityClient.getInstance().activityResumed(token, client.isHandleSplashScreenExit(token));
    }
ActivityClient.java
public void activityResumed(IBinder token, boolean handleSplashScreenExit) {
        try {
            getActivityClientController().activityResumed(token, handleSplashScreenExit);
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        }
    }

https://blog.youkuaiyun.com/xiaoyantan/article/details/126986441

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值