Android的常识体系搭建

AMS系列

AMS之AMS的发动流程

AMS之进程的发动流程

AMS之进程办理LRU算法

AMS的内存办理ADJ算法

[AMS之Activity栈办理(上篇)]-本篇

一 概述

之前说到了 Activity 的发动,今日咱们就说说 Activity 的发动中,关于栈办理的部分。咱们应该经常听说过各种 Activity 栈,比如 Activity 的四种发动形式,其中就有 singleTask 栈内仅有这个形式。那么 Activity 的栈,究竟是一个什么东西,Android 体系对于 Activity 的栈,又是怎么进行办理的,今日,咱们就来具体说一说。

1.1 相关常识

之前在咱们的 Activity 发动流程中,咱们现已大概了解到了 Activity 发动过程中,需求哪些类共同参加工作,今日咱们再介绍一次,在 Activity 栈办理中,这些重要的类。

1.2 ActivityStackSupervisor

ActivityStackSupervisor 这个类,咱们看类名也能猜到,它是 Activity 栈的办理者。

1.3 ActivityRecord

ActivityRecord 是 Activity 在 Android 体系中的记载,它记载了 Activity 里悉数的信息,包括这个 Activity 在 Manifest 中的装备信息,还有这个 Activity 运行在哪个栈,哪个运用等等。它确认了 Activity 在体系中的仅有性。咱们在【三 ActivityRecord】中它进行了具体介绍。

1 .4 Task

它的前身是 ActivityStack,可是从 Android 12 开端,谷歌删除了 ActivityStack 这个概念,悉数运用 Task 进行替代,它代表了 Activity 的栈,

首要仍是要从 AMS 的 startActivityAsUser 说起,具体的 Activity 发动流程能够看 Activity发动源码解析。

二 Activity 的发动与栈

2.1 startActivityAsUser

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");
    userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
            Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
    // 获取 一个 ActivityStartController,然后经过它获取一个 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();
}

在 AMS 发动 Activity 时,出现了这么几个方针 ActivityStartControllerActivityStarter 还有 ActivityRecord。咱们先一个个看。

  • 首要是 ActivityStartController,它是 ActivityStarter 的控制者,用于构建一个能够复用的 ActivityStarter。
  • 然后是 ActivityStarter,它是 Activity 的发动器,它是能够复用的。
  • 最终是 ActivityRecord,它是 Android 体系用于记载 Activity 信息的方针。

咱们先来看一看 ActivityRecord 的创立代码。

2.2 execute

int execute() {
    try {
        // Refuse possible leaked file descriptors
        if (mRequest.intent != null && mRequest.intent.hasFileDescriptors()) {
                throw new IllegalArgumentException("File descriptors passed in Intent");
        }
        final LaunchingState launchingState;
        synchronized (mService.mGlobalLock) {
                // 在前面的发动流程中,咱们现已介绍了,resultTo 便是调用者 Activity。
                // 假如是从非 Activity 的 Context 中调用过来的话,它便是 null
                // forTokenLocked 见 【3.7 forTokenLocked】
                final ActivityRecord caller = ActivityRecord.forTokenLocked(mRequest.resultTo);
                final int callingUid = mRequest.realCallingUid == Request.DEFAULT_REAL_CALLING_UID
                                ?  Binder.getCallingUid() : mRequest.realCallingUid;
                launchingState = mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(
                                mRequest.intent, caller, callingUid);
        }
        if (mRequest.activityInfo == null) {
                mRequest.resolveActivity(mSupervisor);
        }
        ...
        // 执行发动恳求
        res = executeRequest(mRequest);
    ...
}

在前面 Activity 发动流程中,咱们介绍了 resultTo 这个方针,这儿咱们再简略说一下,具体的内容能够看上一篇博客。

现在咱们假定从 Activity A 中发动 Activity B,那么这个 Activity A 便是这个 resultTo 方针。后续咱们将 Activity A 称为源 Activity,将 Activity B 称为方针 Activity

这儿创立 ActivityRecord 里记载了要发动的方针 Activity 信息,传入的参数是源 Activity。接下来咱们再说一说 ActivityRecord 这个方针。

三 ActivityRecord

首要,我先介绍一下 ActivityRecord 中的一些重要的成员变量,ActivityRecord 由于要记载 Activity 的具体信息,所以里边有非常多的成员变量,这儿咱们只罗列一些比较重要的,

3.1 ActivityRecord

[frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java]
final class ActivityRecord extends WindowToken implements WindowManagerService.AppFreezeListener {
    final ActivityTaskManagerService mAtmService;
    // AndroidManifest中的信息
    final ActivityInfo info; 
    // TODO: rename to mActivityToken
    final ActivityRecord.Token appToken;
    final int mUserId;
    // 包名
    final String packageName;
    // 组件名
    final ComponentName mActivityComponent;
    // 这个 Activity 属于哪个 Task
    private Task task; 
    // 谁发动了此 Activity,发动此 Activity 的 Activity 信息
    ActivityRecord resultTo;
    // 栈的亲和性
    final String taskAffinity;
}

ActivityRecord 里记载的信息非常多,咱们需求要点重视的这儿我现已罗列出来了,需求留意的是,从 Android 10 开端,ActivityRecord 这个类就开端发生了改变,所以假如你看的是 Android 10 的代码,task 对应的类型是 TaskRecord,而这个类从 Android 11 开端则变成了 Task。它表明的是这个 Activity 地点的栈。

3.2 Task

[frameworks/base/services/core/java/com/android/server/wm/Task.java]
class Task extends WindowContainer<WindowContainer> {
	...
}

Task 承继的是 WindowContainer,这是 WMS 中的一些概念,这儿就不过多扩展了,后续讲 WMS 的时候再细说,咱们只需求知道,它表明的是 Activity 当时地点的栈即可。

3.3 ActivityRecord 的结构函数

[frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java]
final class ActivityRecord extends WindowToken implements WindowManagerService.AppFreezeListener {
    private ActivityRecord(ActivityTaskManagerService _service, WindowProcessController _caller,
                    int _launchedFromPid, int _launchedFromUid, String _launchedFromPackage,
                    @Nullable String _launchedFromFeature, Intent _intent, String _resolvedType,
                    ActivityInfo aInfo, Configuration _configuration, ActivityRecord _resultTo,
                    String _resultWho, int _reqCode, boolean _componentSpecified,
                    boolean _rootVoiceInteraction, ActivityTaskSupervisor supervisor,
                    ActivityOptions options, ActivityRecord sourceRecord, PersistableBundle persistentState,
                    TaskDescription _taskDescription, long _createTime) {
            super(_service.mWindowManager, new Token(_intent).asBinder(), TYPE_APPLICATION, true,
                            null /* displayContent */, false /* ownerCanManageAppTokens */);
            mAtmService = _service;
            appToken = (Token) token;
            appToken.attach(this);
            ...
}

在 ActivityRecord 的结构函数中,保存了一个 token 为 appToken,并调用了 appToken 的 attach。Token 也是 WMS 中的概念,可是这儿的需求具体阐明一下。token 是 ActivityRecord 父类 WindowToken 中的一个成员变量。

3.4 WindowToken

class WindowToken extends WindowContainer<WindowState> {
    private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowToken" : TAG_WM;
    /** The actual token */
    final IBinder token;
    protected WindowToken(WindowManagerService service, IBinder _token, int type,
            boolean persistOnEmpty, DisplayContent dc, boolean ownerCanManageAppTokens) {
        this(service, _token, type, persistOnEmpty, dc, ownerCanManageAppTokens,
                false /* roundedCornerOverlay */, false /* fromClientToken */, null /* options */);
    }
    protected WindowToken(WindowManagerService service, IBinder _token, int type,
            boolean persistOnEmpty, DisplayContent dc, boolean ownerCanManageAppTokens,
            boolean roundedCornerOverlay, boolean fromClientToken, @Nullable Bundle options) {
        super(service);
        token = _token;
        windowType = type;
        mOptions = options;
        mPersistOnEmpty = persistOnEmpty;
        mOwnerCanManageAppTokens = ownerCanManageAppTokens;
        mRoundedCornerOverlay = roundedCornerOverlay;
        mFromClientToken = fromClientToken;
        if (dc != null) {
            dc.addWindowToken(token, this);
        }
    }
}

咱们能够看到,token 它界说的是一个 IBinder,联系之前 ActivityRecord 传入的实际上是 Intent,所以 Token 其实是经过 Intent 结构出来的。咱们再来看一下 Token 的界说。它其实是 ActivityRecord 中的一个内部类。

3.5 Token

[frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java]
static class Token extends IApplicationToken.Stub {
	private WeakReference<ActivityRecord> weakActivity;
	private final String name;
	private final String tokenString;
	Token(Intent intent) {
		name = intent.getComponent().flattenToShortString();
		tokenString = "Token{" + Integer.toHexString(System.identityHashCode(this)) + "}";
	}
	private void attach(ActivityRecord activity) {
		if (weakActivity != null) {
			throw new IllegalStateException("Already attached..." + this);
		}
		weakActivity = new WeakReference<>(activity);
	}
	private static @Nullable ActivityRecord tokenToActivityRecordLocked(Token token) {
		if (token == null) {
			return null;
		}
		ActivityRecord r = token.weakActivity.get();
		if (r == null || r.getRootTask() == null) {
			return null;
		}
		return r;
	}
	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder(128);
		sb.append("Token{");
		sb.append(Integer.toHexString(System.identityHashCode(this)));
		sb.append(' ');
		if (weakActivity != null) {
			sb.append(weakActivity.get());
		}
		sb.append('}');
		return sb.toString();
	}
	@Override
	public String getName() {
		return name;
	}
}

Token 是 ActivityRecord 的内部成员类,而它的结构函数,其实便是从 Intent 中取出对应的组件名。

3.6 浅谈 Token

再从 ActivityRecord 的结构函数开端说起,首要,Activity 发动时,会创立一个 Intent 保存需求发动 Activity 的组件信息。然后会创立 ActivityRecord,即将方针 Activity 的信息保存起来。

ActivityRecord 的父类 WindowToken 中,有一个 token 方针,ActivityRecord 会将这个 token 保存为一个 appToken,然后调用 Token 的 attach,传入的参数是 ActivityRecord 自己 this。

在做了上述事情之后,现在 ActivityRecord 中有一个 appToken,它的父类 WindowToken 有一个 token。其实这两个方针是同一个 token。而这个 token 里保存了要发动 Activity 的组件名,还保存了要发动 Activity 对应的 ActivityRecord。

现在想一想,Android 为什么要做这些事?其实反过来问一个问题,Android 体系的不同进程中,Activity 是怎么传递的?Android 体系又怎么保证不同进程,能找到而且办理同一个 Activity?

想理解了这些,其实就理解了 token 的效果,它其实就和网络恳求中的 token 相同,一个 token 对应了一个体系中的 Activity。而为了保证 token 在不同进程中的仅有性,那么它为什么承继自 IBinder 就能够理解了。

也便是说,一个 ActivityRecord 对应一个 token,而一个 ActivityRecord 又对应一个 Activity,所以,经过 token 就保证了 Activity 在体系中的仅有性

3.7 forTokenLocked

说完了关于 ActivityRecord 中 token 和 task 的相关内容,咱们接着回到 Activity 发动流程中的 executeRequest ,在其中有这样一行代码 sourceRecord = ActivityRecord.isInAnyTask(resultTo),现在咱们看这行代码应该就能够理解了。forTokenLocked 是界说在 Token 中的函数,前面现已悉数列出来了 Token 的代码,这儿再简略罗列一下。

static @Nullable ActivityRecord forTokenLocked(IBinder token) {
    try {
        return Token.tokenToActivityRecordLocked((Token)token);
    } catch (ClassCastException e) {
        Slog.w(TAG, "Bad activity token: " + token, e);
        return null;
    }
}
private static @Nullable ActivityRecord tokenToActivityRecordLocked(Token token) {
    if (token == null) {
            return null;
    }
    ActivityRecord r = token.weakActivity.get();
    if (r == null || r.getRootTask() == null) {
            return null;
    }
    return r;
}

Token 的结构咱们全面现已解说了,它在 ActivityRecord 中创立,并调用对应的 attach 函数,而 resultTo 表明的是此次发动的源 Activity。所以经过 ActivityRecord.isInAnyTask(resultTo) 就能够拿到这次发动源 Activity 对应的 ActivityRecord。

而前面咱们现已说了 ActivityRecord 中的 task 保存的是这个 Activity 地点的栈,而拿到了源 Activity 的 ActivityRecord,那么也便是拿到了它地点的栈。

那么,拿到了源 Activity 的栈,接下来需求做什么?

明显,相比你现已猜到了,接下来体系需求根据方针 Activity 的发动形式,来判别方针 Activity 地点的栈,是否需求和源 Activity 的栈共同,是需求新建一个栈,仍是复用旧的栈。是否需求铲除旧栈中的 Activity 等等。

接着说 Activity 发动流程中,非常重要的一个函数 startActivityInner。

四 startActivityInner

前面在 Activity 的发动流程中,介绍了 startActivityInner 这个函数,可是当时并没有具体阐明,今日咱们再来说一下。

[frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java]
int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, Task inTask,
              boolean restrictedBgActivity, NeededUriGrants intentGrants) {
    // 设置初始状况
    setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
            voiceInteractor, restrictedBgActivity);
    // 首要便是核算 Activity 的发动形式
    // 获得一个的 Flag,这玩意便是咱们设置给 Intent 的。
    computeLaunchingTaskFlags();
    // 处理源 Activity 的使命栈
    // 假如源 Activity 正在 finish 则需求开启一个新的栈
    computeSourceRootTask();
    // mLaunchFlags 便是前面核算的,这儿设置给 mIntent
    // 其实和咱们发动 Activity 时自界说 Flag 很像
    mIntent.setFlags(mLaunchFlags);
    // Reusable 复用,这儿是获取能够复用的 Task
    final Task reusedTask = getReusableTask();
    //是否需求冻住 Task 列表
    // ?什么什么时候需求冻住
    if (mOptions != null && mOptions.freezeRecentTasksReordering()
            && mSupervisor.mRecentTasks.isCallerRecents(r.launchedFromUid)
            && !mSupervisor.mRecentTasks.isFreezeTaskListReorderingSet()) {
        mFrozeTaskList = true;
        mSupervisor.mRecentTasks.setFreezeTaskListReordering();
    }
    // 是否存在一个能够现在运用的 Task
    // 是否有复用,假如没有,是否能够核算获取一个
    final Task targetTask = reusedTask != null ? reusedTask : computeTargetTask();
    // 假如没有能够现在运用的 Task,那么就创立一个新 Task
    final boolean newTask = targetTask == null;
    mTargetTask = targetTask;
    // 核算发动参数
    computeLaunchParams(r, sourceRecord, targetTask);
    // 判别是否能够经过 targetTask 或者新建 Task 发动的 Activity
    int startResult = isAllowedToStart(r, newTask, targetTask);
    if (startResult != START_SUCCESS) {
        return startResult;
    }
    // 获取栈顶没有 finish 的 activity
    final ActivityRecord targetTaskTop = newTask
            ? null : targetTask.getTopNonFinishingActivity();
    if (targetTaskTop != null) {
        // 看一下栈顶的 Task targetTaskTop 是否能够收回复用
        startResult = recycleTask(targetTask, targetTaskTop, reusedTask, intentGrants);
        if (startResult != START_SUCCESS) {
            return startResult;
        }
    } else {
        mAddingToTask = true;
    }
    // 假如要发动的 Activity 与当时在顶部的 Activity 相同,那么 咱们需求查看它是否应该只被发动一次。
    final Task topRootTask = mPreferredTaskDisplayArea.getFocusedRootTask();
    if (topRootTask != null) {
        startResult = deliverToCurrentTopIfNeeded(topRootTask, intentGrants);
        if (startResult != START_SUCCESS) {
            return startResult;
        }
    }
    if (mTargetRootTask == null) {
        // 获得一个栈 Task
        mTargetRootTask = getLaunchRootTask(mStartActivity, mLaunchFlags, targetTask, mOptions);
    }
    if (newTask) {
        // 假如是新建 Task
        final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
                ? mSourceRecord.getTask() : null;
        // 关联 Task 与 ActivityRecord
        // 这个函数也会调用 addOrReparentStartingActivity
        setNewTask(taskToAffiliate);
    } else if (mAddingToTask) {
        // 即将发动的 Activity 增加到 targetTask
        // 而且会将此 Activity 增加到最近发动的 ActivityRecord 中,后续能够经过 findActivity 复用
        addOrReparentStartingActivity(targetTask, "adding to task");
    }
    if (!mAvoidMoveToFront && mDoResume) {
        mTargetRootTask.getRootTask().moveToFront("reuseOrNewTask", targetTask);
        if (mOptions != null) {
            if (mOptions.getTaskAlwaysOnTop()) {
                mTargetRootTask.setAlwaysOnTop(true);
            }
        }
        if (!mTargetRootTask.isTopRootTaskInDisplayArea() && mService.mInternal.isDreaming()) {
            // 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;
        }
    }
    ...
    // 将 Task 移动到 Activity 栈顶
    mTargetRootTask.startActivityLocked(mStartActivity,
            topRootTask != null ? topRootTask.getTopNonFinishingActivity() : null, newTask,
            mKeepCurTransition, mOptions, sourceRecord);
    if (mDoResume) {
        final ActivityRecord topTaskActivity =
                mStartActivity.getTask().topRunningActivityLocked();
        // 要发动的 Activity 无法获取焦点
        if (!mTargetRootTask.isTopActivityFocusable()
                || (topTaskActivity != null && topTaskActivity.isTaskOverlay()
                && mStartActivity != topTaskActivity)) {
            // 假如 Activity 不行见就无法康复
            // 如有要保证可见,就会触发进入动画
            // 而且,被掩盖的 Activity,直到掩盖物被移除前,都是不行见的
            mTargetRootTask.ensureActivitiesVisible(null /* starting */,
                    0 /* configChanges */, !PRESERVE_WINDOWS);
            // 告知 WMS 持续执行,由于现在 Activity 还无法康复。
            mTargetRootTask.mDisplayContent.executeAppTransition();
        } else {
            if (mTargetRootTask.isTopActivityFocusable()
                    && !mRootWindowContainer.isTopDisplayFocusedRootTask(mTargetRootTask)) {
                mTargetRootTask.moveToFront("startActivityInner");
            }
            // 【要点】康复栈顶的 Activity
            mRootWindowContainer.resumeFocusedTasksTopActivities(
                    mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);
        }
    }
    // 更新 RootTask
    mRootWindowContainer.updateUserRootTask(mStartActivity.mUserId, mTargetRootTask);
    // Activity 发动时立即更新最近的使命列表
    mSupervisor.mRecentTasks.add(mStartActivity.getTask());
    mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(),
            mPreferredWindowingMode, mPreferredTaskDisplayArea, mTargetRootTask);
    return START_SUCCESS;
}

4.1 setInitialState

首要是 setInitialState 这个函数,setInitialState 的字面意思是设置初始化状况。什么是初始化状况呢?其实便是指定发动时的那一堆 m 开头的成员变量,例如 mStartActivity,mIntent 等等。

private void setInitialState(ActivityRecord r, ActivityOptions options, Task inTask,
        boolean doResume, int startFlags, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        boolean restrictedBgActivity) {
    reset(false /* clearRequest */);
    mStartActivity = r;
    mIntent = r.intent;
    mOptions = options;
    mCallingUid = r.launchedFromUid;
    mSourceRecord = sourceRecord;
    mVoiceSession = voiceSession;
    mVoiceInteractor = voiceInteractor;
    mRestrictedBgActivity = restrictedBgActivity;
    ...
}

4.2 computeLaunchingTaskFlags

computeLaunchingTaskFlags 这个函数的效果,便是核算要发动 Activity 所需求的栈参数(Flags)。

private void computeLaunchingTaskFlags() {
    // 留意:咱们之前讲过了 Activity 和 Context 发动 Activity 导致的不同的参数,在这儿就产生了效果。
    // 假如是从 Activity 发动的新 Activity,那么 mSourceRecord 就不会为空。
    if (mSourceRecord == null && mInTask != null && mInTask.getRootTask() != null) {
	    // 假如 mSourceRecord 为空,便是阐明不是 Activity 发动的
        ...
    // 对不同发动形式的处理
    // mInTask 是指定的方针 Activity 的发动栈,
    // 咱们正常从 Activity 发动其他 Activity 时这个参数为空
    // mSourceRecord 是源 Activity 的信息。
    if (mInTask == null) {
        if (mSourceRecord == null) {
            // 假如没有源 Activity 栈信息,就增加一个 FLAG_ACTIVITY_NEW_TASK
            if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && mInTask == null) {
                mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
            }
        } else if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) {
            // 假如源 Activity 是 SingleInstance,那么就需求新开一个栈来发动方针 Activity,
            // 其实便是增加一个 FLAG_ACTIVITY_NEW_TASK 标志
            mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
        } else if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
            // 假如方针 Activity 的发动形式是 SingleInstance 或 SingleTask,也需求新开一个栈
            mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
        }
    }
}

看到这儿,咱们基本就理解了不同 Activity 的发动形式,对应的 Activity 栈是怎么办理的。

  • 从非 Activity 上下文中发动 Activity,需求 FLAG_ACTIVITY_NEW_TASK。
  • 从 SingleInstance 的 Activity 中,发动其他 Activity,不论这个 Activity 是什么形式,都会增加一个 FLAG_ACTIVITY_NEW_TASK
  • 假如方针 Activity 是 SingleInstance 或 SingleTask,也需求新开一个栈

4.3 computeSourceRootTask

private void computeSourceRootTask() {
    // 假如 mSourceRecord 为空,或者 mSourceRecord 现已 finish,mSourceRootTask 都为空
    if (mSourceRecord == null) {
            mSourceRootTask = null;
            return;
    }
    if (!mSourceRecord.finishing) {
            // 假如没有finish,就从 mSourceRecord 中取出 Task
            mSourceRootTask = mSourceRecord.getRootTask();
            return;
    }
    // 铲除 mSourceRecord
    if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0) {
            mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
            mNewTaskInfo = mSourceRecord.info;
            final Task sourceTask = mSourceRecord.getTask();
            mNewTaskIntent = sourceTask != null ? sourceTask.intent : null;
    }
    mSourceRecord = null;
    mSourceRootTask = null;
}

computeSourceRootTask 其实是核算源 Activity 的地点栈,当然它的逻辑很简略,便是假如源 Activity 没有 finish,那么直接取它的 RootTask 就行了。

[frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java]
Task getRootTask() {
	return task != null ? task.getRootTask() : null;
}

4.4 getReusableTask

getReusableTask 是获取能够复用的栈,前面咱们现已拿到了源 Activity 的栈。

private Task getReusableTask() {
    // 假如指名了 Task,那么就直接从容器里取
    ...
    // 开端判别 Activity 的发动形式
    if (putIntoExistingTask) {
        if (LAUNCH_SINGLE_INSTANCE == mLaunchMode) {
            // 发动形式是 singleInstance 则从前史 Activity 中找
            intentActivity = mRootWindowContainer.findActivity(mIntent, mStartActivity.info,
                   mStartActivity.isActivityTypeHome());
        } else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
            // 假如是分屏显现也从前史 Activity 中找
            intentActivity = mRootWindowContainer.findActivity(mIntent, mStartActivity.info,
                    !(LAUNCH_SINGLE_TASK == mLaunchMode));
        } else {
            // 其他状况则找能够复用的 Task
            intentActivity =
                    mRootWindowContainer.findTask(mStartActivity, mPreferredTaskDisplayArea);
        }
    }
    ...
    return intentActivity != null ? intentActivity.getTask() : null;
}

获取能够复用的 Task,根据需求发动的方针 Acitivity,判别是复用现有 Task,仍是创立新的。这儿咱们主要看处理 Activity 发动形式的代码。

  • 首要是判别发动形式是否是 singleInstance,假如是,则先查找前史 Activity。明显,体系需求保证 singleInstance 的 Activity 实例是仅有的。
  • 然后是分屏的,也需求先查找前史 Activity
  • 最终则是其他形式,悉数调用 findTask

咱们接下来看一下这个前史 Activity 的查找逻辑,不过在看 Activity 的查找逻辑之前,咱们需求看一下 recycleTask 这个函数。

4.5 recycleTask

int recycleTask(Task targetTask, ActivityRecord targetTaskTop, Task reusedTask,
		NeededUriGrants intentGrants) {
    ...
    complyActivityFlags(targetTask,
                    reusedTask != null ? reusedTask.getTopNonFinishingActivity() : null, intentGrants);
    ...
    return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP;
}

recycleTask 这个函数也很长,咱们需求留意的是它其中调用了 complyActivityFlags 这样一个函数。

4.6 complyActivityFlags

complyActivityFlags 这个函数的意思,便是要对 Activity 的各种 Flag 进行运用了。

private void complyActivityFlags(Task targetTask, ActivityRecord reusedActivity,
		NeededUriGrants intentGrants) {
    ActivityRecord targetTaskTop = targetTask.getTopNonFinishingActivity();
    final boolean resetTask = reusedActivity != null && (mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0;
    if (resetTask) {
        targetTaskTop = mTargetRootTask.resetTaskIfNeeded(targetTaskTop, mStartActivity);
    }
    if ((mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
                    == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) {
        // 首要就判别方针 Activity 的 Flag 是否有 FLAG_ACTIVITY_NEW_TASK 和 
        // FLAG_ACTIVITY_CLEAR_TASK,这两个咱们很熟悉,一个是新建栈,一个是铲除栈顶
        targetTask.performClearTaskLocked();
        targetTask.setIntent(mStartActivity);
            mAddingToTask = true;
    } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
        || isDocumentLaunchesIntoExisting(mLaunchFlags)
        || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK,
            LAUNCH_SINGLE_INSTANCE_PER_TASK)) {
        // LAUNCH_SINGLE_INSTANCE 和 LAUNCH_SINGLE_TASK
        // 假如有 FLAG_ACTIVITY_CLEAR_TOP,就需求铲除栈顶
        final ActivityRecord top = targetTask.performClearTaskForReuseLocked(mStartActivity,
                            mLaunchFlags);
        // 【要点】这儿的 if 便是Activity栈顶复用的逻辑
        // 假如铲除栈顶之后能拿到方针 Activity
        if (top != null) {
            if (top.isRootOfTask()) {
                // 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);
            }
            // 设置 NewIntent 参数,这便是 Activity 栈顶复用时会调用 NewIntent 的原因了
            deliverNewIntent(top, intentGrants);
        } else {
            // 铲除栈顶后,当时栈仍是没有方针 Activity
            mAddingToTask = true;
            if (targetTask.getRootTask() == null) {
                // 获取发动栈,走发动流程
                mTargetRootTask = getLaunchRootTask(mStartActivity, mLaunchFlags,
                        null /* task */, mOptions);
                mTargetRootTask.addChild(targetTask, !mLaunchTaskBehind /* toTop */,
                                (mStartActivity.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0);
            }
        }
    } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) == 0 && !mAddingToTask
                    && (mLaunchFlags & FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
        // 假如 Activity 不需求铲除栈顶,而且 Flag 是移动到前台
        final ActivityRecord act = targetTask.findActivityInHistory(mStartActivity.mActivityComponent);
        // 假如栈内有 Activity 就把它移动到前台
        if (act != null) {
            final Task task = act.getTask();
            task.moveActivityToFrontLocked(act);
            act.updateOptionsLocked(mOptions);
            deliverNewIntent(act, intentGrants);
            mTargetRootTask.mLastPausedActivity = null;
        } else {
            mAddingToTask = true;
        }
    } else if (mStartActivity.mActivityComponent.equals(targetTask.realActivity)) {
        if (targetTask == mInTask) {
        } else if (((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
            || LAUNCH_SINGLE_TOP == mLaunchMode)
            && targetTaskTop.mActivityComponent.equals(mStartActivity.mActivityComponent)
            && mStartActivity.resultTo == null) {
            // 假如是 FLAG_ACTIVITY_SINGLE_TOP 发动形式,就直接判别栈顶即可
            if (targetTaskTop.isRootOfTask()) {
                targetTaskTop.getTask().setIntent(mStartActivity);
            }
            // 有就设置 NewIntent 参数
            deliverNewIntent(targetTaskTop, intentGrants);
        } else if (!targetTask.isSameIntentFilter(mStartActivity)) {
                mAddingToTask = true;
        } else if (reusedActivity == null) {
                mAddingToTask = true;
        }
    } else if (!resetTask) {
            mAddingToTask = true;
    } else if (!targetTask.rootWasReset) {
            targetTask.setIntent(mStartActivity);
    }
}

complyActivityFlags 中分别对 Activity 的三种特殊发动形式分别做了处理 singleTop,singleTask 还有 singleInstance,而且还判别了是否有铲除栈顶的参数 Flag,然后调用 deliverNewIntent 设置 NewIntent 参数。

4.7 deliverNewIntent

private void deliverNewIntent(ActivityRecord activity, NeededUriGrants intentGrants) {
    if (mIntentDelivered) {
            return;
    }
    activity.logStartActivity(EventLogTags.WM_NEW_INTENT, activity.getTask());
    activity.deliverNewIntentLocked(mCallingUid, mStartActivity.intent, intentGrants,
                    mStartActivity.launchedFromPackage);
    mIntentDelivered = true;
}

4.8 deliverNewIntentLocked

[frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java]
final void deliverNewIntentLocked(int callingUid, Intent intent, NeededUriGrants intentGrants,
		String referrer) {
    mAtmService.mUgmInternal.grantUriPermissionUncheckedFromIntent(intentGrants,
                    getUriPermissionsLocked());
    final ReferrerIntent rintent = new ReferrerIntent(intent, referrer);
    boolean unsent = true;
    final boolean isTopActivityWhileSleeping = isTopRunningActivity() && isSleeping();
    if ((mState == RESUMED || mState == PAUSED || isTopActivityWhileSleeping)
            && attachedToProcess()) {
        try {
                // 假如 Activity 当时处于 RESUMED,PAUSED 或者正在顶部休眠
                ArrayList<ReferrerIntent> ar = new ArrayList<>(1);
                ar.add(rintent);
                // 保证事务完成后状况为 RESUMED,而且立刻调用 NewIntent
                mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
                                NewIntentItem.obtain(ar, mState == RESUMED));
                unsent = false;
        } catch (RemoteException e) {
                Slog.w(TAG, "Exception thrown sending new intent to " + this, e);
        } catch (NullPointerException e) {
                Slog.w(TAG, "Exception thrown sending new intent to " + this, e);
        }
    }
    // 假如不为上述状况,则将 rintent 保存
    if (unsent) {
        addNewIntentLocked(rintent);
    }
}

4.9 addNewIntentLocked

// newIntents 是 ActivityRecord 中的成员变量
ArrayList<ReferrerIntent> newIntents; // any pending new intents for single-top mode
private void addNewIntentLocked(ReferrerIntent intent) {
    if (newIntents == null) {
        newIntents = new ArrayList<>();
    }
    newIntents.add(intent);
}

到此,NewIntent 咱们就处理完了,记住这个 newIntents 变量,后边它还会出现。

五 RootWindowContainer

5.1 findActivity

ActivityRecord findActivity(Intent intent, ActivityInfo info, boolean compareIntentFilters) {
    // ComponentName = 包名 + Activity 类名
    ComponentName cls = intent.getComponent();
    if (info.targetActivity != null) {
        cls = new ComponentName(info.packageName, info.targetActivity);
    }
    final int userId = UserHandle.getUserId(info.applicationInfo.uid);
    // 留意,这儿传入的参数 RootWindowContainer::matchesActivity。
    // 在【5.2】中需求运用
    final PooledPredicate p = PooledLambda.obtainPredicate(
            RootWindowContainer::matchesActivity, PooledLambda.__(ActivityRecord.class),
            userId, compareIntentFilters, intent, cls);
    // 查找能够复用的 Activity
    final ActivityRecord r = getActivity(p);
    p.recycle();
    return r;
}

5.2 getActivity

ActivityRecord getActivity(Predicate<ActivityRecord> callback, boolean traverseTopToBottom,
        ActivityRecord boundary) {
    return callback.test(this) ? this : null;
}

这儿仅仅调用了传入的 callback.test,这个 callback 是哪里来的呢?在之前的 RootWindowContainer.findActivity 中,咱们创立了一个 PooledPredicate,它的第一个参数便是 RootWindowContainer::matchesActivity。
这个参数是一个函数,这儿的 test 会调用到这个函数,这个函数的姓名 matchesActivity 咱们就能够看出来,它是用来匹配 Activity 的。

5.3 matchesActivity

[frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java]
private static boolean matchesActivity(ActivityRecord r, int userId,
        boolean compareIntentFilters, Intent intent, ComponentName cls) {
    if (!r.canBeTopRunning() || r.mUserId != userId) return false;
    if (compareIntentFilters) {
        if (r.intent.filterEquals(intent)) {
            return true;
        }
    } else {
        // Compare the target component instead of intent component so we don't miss if the
        // activity uses alias.
        if (r.mActivityComponent.equals(cls)) {
            return true;
        }
    }
    return false;
}

Activity 匹配有两种状况,第一种便是 IntentFilters 匹配,第二种便是包名 + Activity 类名匹配。所以在 RootWindowContainer.findActivity 中会找到一个符合匹配的 ActivityRecord。

六 computeTargetTask

private Task computeTargetTask() {
    if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
            && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
        // 1. 源Activity为空,方针Activity的发动Flag有FLAG_ACTIVITY_NEW_TASK标志
        return null;
    } else if (mSourceRecord != null) {
        // 2. 源 Activity 不为空
        return mSourceRecord.getTask();
    } else if (mInTask != null) {
        // 3. 有指定的发动栈
        return mInTask;
    } else {
        // 一些其他状况
        final Task rootTask = getLaunchRootTask(mStartActivity, mLaunchFlags, null /* task */,
                mOptions);
        final ActivityRecord top = rootTask.getTopNonFinishingActivity();
        if (top != null) {
            return top.getTask();
        } else {
            // Remove the root task if no activity in the root task.
            rootTask.removeIfPossible("computeTargetTask");
        }
    }
    return null;
}

computeTargetTask 是核算方针 Activity 的栈,假如核算的成果不为 null,就运用核算的成果,假如核算的成果为 null,则会创立一个新的栈。

七 RootWindowContainer

7.1 resumeFocusedTasksTopActivities

[frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java]
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)) {
        // 康复栈顶的 Activity
        result = targetRootTask.resumeTopActivityUncheckedLocked(target, targetOptions,
                        deferPause);
    }
    for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
        final DisplayContent display = getChildAt(displayNdx);
        // 将成果保存到 curResult 中
        final boolean curResult = result;
        boolean[] resumedOnDisplay = new boolean[1];
        display.forAllRootTasks(rootTask -> {
            final ActivityRecord topRunningActivity = rootTask.topRunningActivity();
            if (!rootTask.isFocusableAndVisible() || topRunningActivity == null) {
                    return;
            }
            if (rootTask == targetRootTask) {
                // 更新 curResult 成果
                resumedOnDisplay[0] |= curResult;
                return;
            }
            if (rootTask.getDisplayArea().isTopRootTask(rootTask)
                            && topRunningActivity.isState(RESUMED)) {
                    rootTask.executeAppTransition(targetOptions);
            } else {
                    resumedOnDisplay[0] |= topRunningActivity.makeActiveIfNeeded(target);
            }
        });
        result |= resumedOnDisplay[0];
        if (!resumedOnDisplay[0]) {
            // 前面更新了 resumedOnDisplay[0]
            // 可是假如 resumedOnDisplay[0] 没有内容,那么就需求回到 focusedRoot,
            // 假如 focusedRoot 也没有,就回到 Home Activity
            final Task focusedRoot = display.getFocusedRootTask();
            if (focusedRoot != null) {
                    result |= focusedRoot.resumeTopActivityUncheckedLocked(target, targetOptions);
            } else if (targetRootTask == null) {
                    result |= resumeHomeActivity(null /* prev */, "no-focusable-task",
                                    display.getDefaultTaskDisplayArea());
            }
        }
    }
    return result;
}

resumeFocusedTasksTopActivities 主要的意图便是处理栈顶的 Activity,由于规划到显现的内容,所以会有一些 WMS 相关的常识,这儿咱们先重视康复栈顶的操作 resumeTopActivityUncheckedLocked,它是 Task 中的函数,WMS 相关的常识后边再看。

八 Task

8.1 resumeTopActivityUncheckedLocked

[frameworks/base/services/core/java/com/android/server/wm/Task.java]
@GuardedBy("mService")
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options,
		boolean deferPause) {
    if (mInResumeTopActivity) {
        // 不要开端递归
        return false;
    }
    boolean someActivityResumed = false;
    try {
        // 避免递归
        mInResumeTopActivity = true;
        if (isLeafTask()) {
            // 可见,而且还有焦点
            if (isFocusableAndVisible()) {
                    // 调用康复栈顶的函数 resumeTopActivityInnerLocked
                    someActivityResumed = resumeTopActivityInnerLocked(prev, options, deferPause);
            }
        } else {
            int idx = mChildren.size() - 1;
            while (idx >= 0) {
                final Task child = (Task) getChildAt(idx--);
                if (!child.isTopActivityFocusable()) {
                        continue;
                }
                if (child.getVisibility(null /* starting */) != TASK_VISIBILITY_VISIBLE) {
                        break;
                }
                // 调用 child 的 resumeTopActivityUncheckedLocked
                someActivityResumed |= child.resumeTopActivityUncheckedLocked(prev, options,
                                deferPause);
                if (idx >= mChildren.size()) {
                        idx = mChildren.size() - 1;
                }
            }
        }
        // 当康复顶部活动时,可能需求暂停顶部活动(例如,返回到确定屏幕。 
        // 咱们在{@link #resumeTopActivityUncheckedLocked }中按捺了正常的暂停逻辑,
        // 由于顶部的 Activity 会在结束时康复。 咱们在这儿再次调用{@link ActivityTaskSupervisor #checkReadyForSleepLocked },
        // 以保证发生任何必要的暂停逻辑。 假如不管确定屏幕怎么都将显现“活动”,
        // 则将越过对{@link ActivityTaskSupervisor #checkReadyForSleepLocked }的调用。
        final ActivityRecord next = topRunningActivity(true /* focusableOnly */);
        if (next == null || !next.canTurnScreenOn()) {
                checkReadyForSleep();
        }
    } finally {
        // 最终将 mInResumeTopActivity 设置为 false
        mInResumeTopActivity = false;
    }
    return someActivityResumed;
}

8.2 resumeTopActivityInnerLocked

@GuardedBy("mService")
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options,
		boolean deferPause) {
    // 判别 ATMS 服务是否准备好
    if (!mAtmService.isBooting() && !mAtmService.isBooted()) {
        return false;
    }
    // 在此根使命中查找下一个要持续的、未完成且可获得焦点的最顶层 Activity。
    // 假如它不是可获取焦点的的,咱们将在下一个可获取焦点的栈中持续。
    ActivityRecord next = topRunningActivity(true /* focusableOnly */);
    final boolean hasRunningActivity = next != null;
    if (hasRunningActivity && !isAttached()) {
        return false;
    }
    mRootWindowContainer.cancelInitializingActivities();
    if (!hasRunningActivity) {
        // There are no activities left in the root task, let's look somewhere else.
        return resumeNextFocusableActivityWhenRootTaskIsEmpty(prev, options);
    }
    next.delayedResume = false;
    final TaskDisplayArea taskDisplayArea = getDisplayArea();
    // 假如栈顶的 Activity 现已 Resume,直接返回即可
    // 正常发动此刻 Activity 还没 Resume
    if (mResumedActivity == next && next.isState(RESUMED)
                    && taskDisplayArea.allResumedActivitiesComplete()) {
        ...
        return false;
    }
    if (!next.canResumeByCompat()) {
        return false;
    }
    // 假如咱们正在调用 Activity 的 pause,那么在它 pause 之前不要做任何事情。
    final boolean allPausedComplete = mRootWindowContainer.allPausedActivitiesComplete();
    if (!allPausedComplete) {
            return false;
    }
    // 假如当时 Activity 是 pause 而且休眠中,直接返回
    if (mLastPausedActivity == next && shouldSleepOrShutDownActivities()) {
            ...
            return false;
    }
    ...
    // 【重要】Pausing 掉现在正 Resume 的 Activity
    boolean pausing = !deferPause && taskDisplayArea.pauseBackTasks(next);
    ...
    if (pausing) {
        ProtoLog.v(WM_DEBUG_STATES, "resumeTopActivityLocked: Skip resume: need to"
                        + " start pausing");
        if (next.attachedToProcess()) {
            // 更新进程到 LRU 行列,这个函数在 ProcessRecord.java 中
            next.app.updateProcessInfo(false /* updateServiceConnectionActivities */,
                            true /* activityChange */, false /* updateOomAdj */,
                            false /* addPendingTopUid */);
        } else if (!next.isProcessRunning()) {
            // 假如进程还没发动,先发动进程
            final boolean isTop = this == taskDisplayArea.getFocusedRootTask();
            mAtmService.startProcessAsync(next, false /* knownToBeDead */, isTop,
                                isTop ? "pre-top-activity" : "pre-activity");
        }
        if (lastResumed != null) {
            lastResumed.setWillCloseOrEnterPip(true);
        }
        return true;
    } else if (mResumedActivity == next && next.isState(RESUMED)
            && taskDisplayArea.allResumedActivitiesComplete()) {
        executeAppTransition(options);
        return true;
    }
    ...
    if (next.attachedToProcess()) {
        // 假如  Activity 现已与 Process 绑定,则执行下面的函数
        // 走生命周期 A.onPause -> B.onResume
        try {
            // 经过 app 的 IBinder 方针和 appToken 获取到它对应的 ClientTransaction
            // app.getThread 在之前的 Activity 发动流程和 AMS 里现已具体讲解过了
            // appToken 在【3.6】中也具体讲解了
            final ClientTransaction transaction =
                            ClientTransaction.obtain(next.app.getThread(), next.appToken);
            // Deliver all pending results.
            ArrayList<ResultInfo> a = next.results;
            if (a != null) {
                    final int N = a.size();
                    if (!next.finishing && N > 0) {
                            // 分发一切的 ActivityResult
                            transaction.addCallback(ActivityResultItem.obtain(a));
                    }
            }
            // 假如有 newIntents,就调用 NewIntent
            if (next.newIntents != null) {
                    transaction.addCallback(
                                    NewIntentItem.obtain(next.newIntents, true /* resume */));
            }
            // 铲除运用的 stopped 状况
            next.notifyAppResumed(next.stopped);
            EventLogTags.writeWmResumeActivity(next.mUserId, System.identityHashCode(next),
                            next.getTask().mTaskId, next.shortComponentName);
            mAtmService.getAppWarningsLocked().onResumeActivity(next);
            next.app.setPendingUiCleanAndForceProcessStateUpTo(mAtmService.mTopProcessState);
            next.abortAndClearOptionsAnimation();
            // 调用 Activity 的 onResume
            transaction.setLifecycleStateRequest(
                            ResumeActivityItem.obtain(next.app.getReportedProcState(),
                                            dc.isNextTransitionForward()));
            // 事情开端
            mAtmService.getLifecycleManager().scheduleTransaction(transaction);
            ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivityLocked: Resumed %s", next);
        } catch (Exception e) {
            ...
            return true;
        }
        // 从这一点开端,假如出现问题,就没有办法康复 Activity。
        try {
                next.completeResumeLocked();
        } catch (Exception e) {
                ...
                return true;
        }
    } else {
        // 假如没有绑定,走 Activity 的发动,发动流程能够看另一篇博客,专门讲 Activity 发动的
        ...
        mTaskSupervisor.startSpecificActivity(next, true, true);
    }
    return true;
}

resumeTopActivityInnerLocked 这段代码很重要,它回答了 A Activity 发动 B Activity 时,Activity 的生命周期执行次序,而且,它还回调了 Activity 发动时的生命周期,假如 Activity 需求栈内复用,NewIntent 也是在这儿回调的。newIntents 这个方针之前咱们在【4.9 addNewIntentLocked】中现已介绍过了。

到此,咱们现已见到源 Activity 发动方针 Activity 的流程了,而在 resumeTopActivityInnerLocked 函数中,做了咱们最熟悉,也经常被问题的一个问题。A Activity 发动 B Activity 的生命周期是怎么走的?

从代码中,咱们能够看到,体系会首要调用源 Activity 的 Pausing,然后再判别方针 Activity,决议是走发动流程,仍是直接走 onResume。

8.3 pauseBackTasks

[frameworks/base/services/core/java/com/android/server/wm/TaskDisplayArea.java]
boolean pauseBackTasks(ActivityRecord resuming) {
    final int[] someActivityPaused = {0};
    forAllLeafTasks((task) -> {
        final ActivityRecord resumedActivity = task.getResumedActivity();
        if (resumedActivity != null
                && (task.getVisibility(resuming) != TASK_VISIBILITY_VISIBLE
                || !task.isTopActivityFocusable())) {
            // 调用 Pausing
            if (task.startPausingLocked(false /* uiSleeping*/,
                    resuming, "pauseBackTasks")) {
                someActivityPaused[0]++;
            }
        }
    }, true /* traverseTopToBottom */);
    return someActivityPaused[0] > 0;
}

最终再来看一下 Pausing 的调用,它其实便是从栈 Task 中取出 Resume 状况的 Activity,并调用它的 startPausingLocked。

九 总结

到此,咱们介绍了 AMS 中,关于 Activity 发动时,栈办理的部分的内容。当然,栈办理是 Activity 发动中的重要内容,而且还触及 AMS,而 Activity 栈显现的内容,还有容器相关的内容又触及到 WMS,这儿就先略过 WMS 相关的内容,后边再具体说。

关于 Activity 的栈办理,分为发动和毁掉两个部分,这篇博客咱们介绍了发动部分的内容,毁掉部分的内容由于篇幅原因,咱们放下一个部分介绍。咱们先就现在的内容做一个简略的总结。

  1. 首要,Activity 发动,分为两个类型,从 Activity 中的发动,和非 Activity 中的发动,这两种发动,决议了发动流程中的 resultTo 是否存在,即源 Activity 的 ActivityRecord。
  2. 方针 Activity 的发动栈核算,取决于它的发动形式,即最终的 mFlag,还有源 Activity 的栈。
  3. 方针 Activity 的发动形式,决议了它发动栈 Task 的核算还有 mFlag,而 Task 中是否有前史 Activity,又决议了方针 Activity 的这次发动的需求执行那些生命周期函数。
  4. 最终便是 Activity 的生命周期函数的回调,这块内容谷歌官方一向在做修正,在 Android 12 中,它的回调分改为了 Callback 加上事情处理的方式,这块内容之前在 Activity 的发动流程中有阐明。

最终再简略阐明一下,Activity 的发动,毁掉,AMS 的栈办理,进程办理等等属于 Android 中的重要内容,而且整个流程极为复杂,只看一遍源码都不一定能弄懂,所以需求反复翻看,之后咱们聊 WMS 还有 Activity 窗口显现的部分内容时,这部分内容还会不断提及。