在 Android 6.0 Launcher 启动 Activity 过程源码分析(一) 分析完了 Launcher 组件中启动的步骤,接下来的环节是该 ActivityManagerService 出场了。
通过 ActivityManagerNative.getDefault() 方法得到 ActivityManagerService 的代理对象后执行的 startActivity 方法,最终会发起进程间通信请求,通过 Binder 驱动,再调用 ActivityManagerService 中对应的方法。
ActivityManagerService 类的 startActivity()方法
1 @Override
2 public final int startActivity(IApplicationThread caller, String callingPackage,
3 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4 int startFlags, ProfilerInfo profilerInfo, Bundle options) {
5 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
6 resultWho, requestCode, startFlags, profilerInfo, options,
7 UserHandle.getCallingUserId());
8 }
显然,最后调用了 startActivityAsUser
方法:
ActivityManagerService 类的 startActivityAsUser()方法
1@Override
2 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
5 // 相关验证过程
6 enforceNotIsolatedCaller("startActivity");
7 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8 false, ALLOW_FULL_ONLY, "startActivity", null);
9 //
10 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
11 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
12 profilerInfo, null, null, options, false, userId, null, null);
13 }
在 startActivityAsUser
先是执行了相关的验证过程,然后调用了类型为 ActivityStackSupervisor
的mStackSupervisor
的startActivityMayWait()
方法。
ActivityStackSupervisor 类的 startActivityMayWait() 方法
Android 中的 Activity 组件堆栈信息,也就是 Task,是用 ActivityStack
类管理的,而ActivityStackSupervisor
则是一个管理所有的ActivityStack
的类。
1 final int startActivityMayWait(IApplicationThread caller, int callingUid,
2 String callingPackage, Intent intent, String resolvedType,
3 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
4 IBinder resultTo, String resultWho, int requestCode, int startFlags,
5 ProfilerInfo profilerInfo, WaitResult outResult, Configuration config,
6 Bundle options, boolean ignoreTargetSecurity, int userId,
7 IActivityContainer iContainer, TaskRecord inTask) {
8 // 省略部分代码
9
10 // Collect information about the target of the Intent.
11 // 通过 PackageManagerService 解析 Intent 参数内容,获得更多信息,保存到 ActivityInfo 类中
12 ActivityInfo aInfo =
13 resolveActivity(intent, resolvedType, startFlags, profilerInfo, userId);
14
15 // 省略部分关于 aInfo 代码
16
17 int res = startActivityLocked(caller, intent, resolvedType, aInfo,
18 voiceSession, voiceInteractor, resultTo, resultWho,
19 requestCode, callingPid, callingUid, callingPackage,
20 realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity,
21 componentSpecified, null, container, inTask);
22
23 Binder.restoreCallingIdentity(origId);
24 return res;
25 }
26 }
27
28// resolveActivity 函数
29 ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
30 ProfilerInfo profilerInfo, int userId) {
31 // Collect information about the target of the Intent.
32 ActivityInfo aInfo;
33 try {
34 ResolveInfo rInfo =
35 AppGlobals.getPackageManager().resolveIntent(
36 intent, resolvedType,
37 PackageManager.MATCH_DEFAULT_ONLY
38 | ActivityManagerService.STOCK_PM_FLAGS, userId);
39 aInfo = rInfo != null ? rInfo.activityInfo : null;
40 } catch (RemoteException e) {
41 aInfo = null;
42 }
43 // 省略部分代码
44
45 }
首先会先调用resolveActivity
函数,通过 PackageManagerService 解析 Intent 得到更多信息,返回ActivityInfo
对象之后,便执行 startActivityLocked
方法。
ActivityStackSupervisor 类的 startActivityLocked() 方法
1final int startActivityLocked(IApplicationThread caller,
2 Intent intent, String resolvedType, ActivityInfo aInfo,
3 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
4 IBinder resultTo, String resultWho, int requestCode,
5 int callingPid, int callingUid, String callingPackage,
6 int realCallingPid, int realCallingUid, int startFlags, Bundle options,
7 boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
8 ActivityContainer container, TaskRecord inTask) {
9 int err = ActivityManager.START_SUCCESS;
10 ProcessRecord callerApp = null;
11 if (caller != null) {
12 callerApp = mService.getRecordForAppLocked(caller); // 得到调用者的 ProcessRecord
13 if (callerApp != null) {
14 callingPid = callerApp.pid; // 调用者的 PID
15 callingUid = callerApp.info.uid; // 调用者的 UID
16 } else {
17 err = ActivityManager.START_PERMISSION_DENIED;
18 }
19 }
20
21 // 省略部分代码 ,得到描述 Launcher 组件的 ActivityRecord 对象,保存在变量 sourceRecord 中
22 ActivityRecord sourceRecord = null;
23 ActivityRecord resultRecord = null;
24 if (resultTo != null) {
25 sourceRecord = isInAnyStackLocked(resultTo);
26 if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
27 "Will send result to " + resultTo + " " + sourceRecord);
28 if (sourceRecord != null) {
29 // 从 Launcher 启动,requestCode 为 -1 ,下面的if不成立,resultRecord 为 null 。
30 if (requestCode >= 0 && !sourceRecord.finishing) {
31 resultRecord = sourceRecord;
32 }
33 }
34 }
35
36 // 创建用来描述被启动的 Activity 组件的 ActivityRecord 。
37 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage, intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null, this, container, options);
38
39 err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
40 startFlags, true, options, inTask);
41}
42
43// 根据 token 找到对应的 ActivityRecord 变量,相当于一个数组变量里面的每个元素又持有一个数组。
44ActivityRecord isInAnyStackLocked(IBinder token) {
45 // mActivityDisplays 变量的类型为 SparseArray<ActivityDisplay>
46 int numDisplays = mActivityDisplays.size();
47 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
48 // 内部持有一个 ArrayList<ActivityStack> 类型的变量 mStacks
49 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
50 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
51 final ActivityRecord r = stacks.get(stackNdx).isInStackLocked(token);
52 if (r != null) {
53 return r;
54 }
55 }
56 }
57 return null;
58 }
每一个应用程序进程都使用一个 ProcessRecord
对象来描述,并且保存在 ActivityManagerService 内部。ActivityStackSupervisor 的 mService 变量指向了ActivityManagerService 。通过它的成员函数getRecordForAppLocked
来获得参数caller
对应的一个ProcessRecord
对象callerApp
。而参数caller
指向的是 Launcher 组件所运行的应用程序进程的一个 ApplicationThread 对象,因此,ProcessRecord
对象 callerApp
实际上就指向了 Launcher 组件所运行的应用程序进程,接着得到这个应用程序进程的 PID 和 UID ,保存在参数callingPid
和callingUid
中。
ActivityStackSupervisor 变量内部有一个变量 mActivityDisplays,类型为SparseArray<ActivityDisplay>
,而ActivityDisplay
变量内部又持有一个mStack
变量,类型为ArrayList<ActivityStack>
,通过找到Activity 组件堆栈 ActivityStack
,从而得到用来描述Launcher
组件的ActivityRecord
对象,保存在变量sourceRecord
中,而由于 requestCode 为 -1 ,则 resultRecord
继续为 null 。
最后,创建了一个 ActivityRecord 对象r
用来描述即将启动的 Activity 组件。
现在,就已经得到请求启动 Activity 组件的 Launcher ActivityRecord 信息sourceRecord
以及需要启动的 Activity 的组件信息r
,下一步就执行startActivityUncheckedLocked
操作。
ActivityStackSupervisor 类的 startActivityUncheckedLocked() 方法
1final int startActivityUncheckedLocked(final ActivityRecord r, ActivityRecord sourceRecord,
2 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, Bundle options, TaskRecord inTask) {
3 final Intent intent = r.intent;
4 final int callingUid = r.launchedFromUid;
5 // 得到目标 Activity 组件的启动标志位
6 int launchFlags = intent.getFlags();
7
8 // We'll invoke onUserLeaving before onPause only if the launching
9 // activity did not explicitly state that this is an automated launch.
10 mUserLeaving = (launchFlags & Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
11
12 boolean addingToTask = false; // 是否将需要启动的 Activity 添加到给定的 task 中
13 TaskRecord reuseTask = null; //
14
15 // If the caller is not coming from another activity, but has given us an
16 // explicit task into which they would like us to launch the new activity,
17 // then let's see about doing that.
18 // 如果调用者
19 if (sourceRecord == null && inTask != null && inTask.stack != null) {
20 // 省略部分代码
21 // If task is empty, then adopt the interesting intent launch flags in to the
22 // activity being started.
23 if (root == null) {
24 final int flagsOfInterest = Intent.FLAG_ACTIVITY_NEW_TASK
25 | Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NEW_DOCUMENT
26 | Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
27 launchFlags = (launchFlags&~flagsOfInterest)
28 | (baseIntent.getFlags()&flagsOfInterest);
29 intent.setFlags(launchFlags);
30 inTask.setIntent(r);
31 addingToTask = true;
32 }
33
34 // 省略启动 Activity 已经启动过的情况,主要是将 Activity 移植 Task 栈顶
35 // 启动一个从未启动过的 Activity
36 boolean newTask = false; // 表示在一个新的 Task 中启动 Activity
37 boolean keepCurTransition = false;
38
39 // Should this be considered a new task?
40 // 是否要创建一个新的 Task ,当然是要的
41 if (r.resultTo == null && inTask == null && !addingToTask
42 && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
43 newTask = true;
44 targetStack = computeStackFocus(r, newTask);
45 targetStack.moveToFront("startingNewTask");
46
47 if (reuseTask == null) { // reuseTask 为 null,创建一个新的 Task
48 r.setTask(targetStack.createTaskRecord(getNextTaskId(),
49 newTaskInfo != null ? newTaskInfo : r.info,
50 newTaskIntent != null ? newTaskIntent : intent,
51 voiceSession, voiceInteractor, !launchTaskBehind /* toTop */),
52 taskToAffiliate);
53 if (DEBUG_TASKS) Slog.v(TAG_TASKS,
54 "Starting new activity " + r + " in new task " + r.task);
55 } else {
56 r.setTask(reuseTask, taskToAffiliate);
57 }
58 if (isLockTaskModeViolation(r.task)) {
59 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
60 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
61 }
62 if (!movedHome) {
63 if ((launchFlags &
64 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
65 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
66 // Caller wants to appear on home activity, so before starting
67 // their own activity we will bring home to the front.
68 r.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
69 }
70 }
71 } else if (sourceRecord != null) {
72 // 上面的 if 判断成立,省略代码
73 // 在调用者的 Task 中做操作 ,resumeTopActivityLocked 方法
74 } else if (inTask != null) {
75 // 上面的 if 判断成立,省略代码
76 // 在指定的 Task 中做操作,
77 } else {
78 // 上面的 if 判断成立,省略代码
79 }
80
81 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
82 intent, r.getUriPermissionsLocked(), r.userId);
83
84 if (sourceRecord != null && sourceRecord.isRecentsActivity()) {
85 r.task.setTaskToReturnTo(RECENTS_ACTIVITY_TYPE);
86 }
87 if (newTask) {
88 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
89 }
90 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
91 targetStack.mLastPausedActivity = null;
92 // 启动 Activity 组件的下一步
93 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
94 if (!launchTaskBehind) {
95 // Don't set focus on an activity that's going to the back.
96 mService.setFocusedActivityLocked(r, "startedActivity");
97 }
98 return ActivityManager.START_SUCCESS;
99}
检查 launchFlags 的 Intent.Flag_ACTIVITY_NO_USER_ACTION
是否等于 1 。如果等于 1,则表示目标 Activity 组件不是由用户手动启动的。如果目标 Activity 组件是由用户手动启动的,那么用来启动它的源 Activity 就会获得一个用户离开事件通知。
由于是从 Launcher 启动 Activity 组件,则 Flag_ACTIVITY_NO_USER_ACTION
等于 0 ,mUserLeaving 为 True ,表示后面要向 Launcher 组件发送一个用户离开事件通知。
由于从 Launcher 启动的 Activity 运行在另一个 Task 中,则 addingToTask 为 false
,同时 reuseTask
也是为 null
的,inTask
为 null
,并且 r.resultTo
是一个 ActivityRecord 类型,由于 Activity 组件还没启动,也是为 null
。所以,最上面的 if 判断成立,直接创建一个新的 Task 了。
ActivityStack 类的 startActivityLocked() 方法
1 final void startActivityLocked(ActivityRecord r, boolean newTask,
2 boolean doResume, boolean keepCurTransition, Bundle options) {
3 TaskRecord rTask = r.task;
4 final int taskId = rTask.taskId;
5 // mLaunchTaskBehind tasks get placed at the back of the task stack.
6 if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) {
7 // Last activity in task had been removed or ActivityManagerService is reusing task.
8 // Insert or replace.
9 // Might not even be in.
10 insertTaskAtTop(rTask, r);
11 mWindowManager.moveTaskToTop(taskId);
12 }
13
14 if (!newTask) {
15 // newTask 为 true ,省略部分代码
16 }
17
18 // Place a new activity at top of stack, so it is next to interact
19 // with the user.
20
21 // If we are not placing the new activity frontmost, we do not want
22 // to deliver the onUserLeaving callback to the actual frontmost activity
23 // task 变量为 null,尚未赋值, IF 判断不成立
24 if (task == r.task && mTaskHistory.indexOf(task) != (mTaskHistory.size() - 1)) {
25 mStackSupervisor.mUserLeaving = false;
26 if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
27 "startActivity() behind front, mUserLeaving=false");
28 }
29
30 task = r.task;
31 // Slot the activity into the history stack and proceed
32 if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to stack to task " + task,
33 new RuntimeException("here").fillInStackTrace());
34 task.addActivityToTop(r);
35 task.setFrontOfTask();
36 r.putInHistory();
37
38 // 省略 Window 添加部分代码
39 if (doResume) {
40 mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
41 }
42 }
43// 将 ActivityRecord 添加到栈的方法
44void addActivityToTop(ActivityRecord r) {
45 addActivityAtIndex(mActivities.size(), r);
46}
在上一步中,已经通过 r.setTask()
方法创建了一个新的 Task,并且 newTask
变量为 true
。当 Activity 是在一个新的 Task 中启动时,需要将它放到 TaskRecord 的中,并且位于堆栈的最上方。
当添加完之后,便继续执行 resumeTopActivitiesLocked
方法。
ActivityStackSupervisor 类的 resumeTopActivitiesLocked() 方法
1boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
2 Bundle targetOptions) {
3 if (targetStack == null) {
4 targetStack = mFocusedStack;
5 }
6 // Do targetStack first.
7 boolean result = false;
8 if (isFrontStack(targetStack)) {
9 // 调用 ActivityStack 类的 resumeTopActivityLocked 方法
10 result = targetStack.resumeTopActivityLocked(target, targetOptions);
11 }
12
13 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
14 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
15 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
16 final ActivityStack stack = stacks.get(stackNdx);
17 if (stack == targetStack) {
18 // Already started above.
19 continue;
20 }
21 if (isFrontStack(stack)) {
22 // 调用 ActivityStack 类的 resumeTopActivityLocked 方法,参数为 null
23 stack.resumeTopActivityLocked(null);
24 }
25 }
26 }
27 return result;
28 }
ActivityStackSupervisor 类重载了两种形式的 resumeTopActivitiesLocked
方法,主要就是将所有ActivityStack栈顶的ActivityRecord迁移到显示状态,都是调用 ActivityStack
类的resumeTopActivityLocked
方法,只不过参数略有不同了。
ActivityStack 类的 resumeTopActivityLocked() 方法
1final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
2 if (mStackSupervisor.inResumeTopActivity) {
3 // Don't even start recursing.
4 return false;
5 }
6
7 boolean result = false;
8 try {
9 // Protect against recursion.
10 mStackSupervisor.inResumeTopActivity = true;
11 if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
12 mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
13 mService.updateSleepIfNeededLocked();
14 }
15 result = resumeTopActivityInnerLocked(prev, options);
16 } finally {
17 mStackSupervisor.inResumeTopActivity = false;
18 }
19 return result;
20 }
在该方法内部最后调用了resumeTopActivityInnerLocked
方法。
ActivityStack 类的 resumeTopActivityInnerLocked() 方法
1 private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
2 // Find the first activity that is not finishing.
3 // 找到当前 ActivityRecord 的栈顶,指向了要启动的 Activity 组件。
4 final ActivityRecord next = topRunningActivityLocked(null);
5 final TaskRecord prevTask = prev != null ? prev.task : null;
6
7 if (next == null) {
8 进入该分支表示没有要启动的 Activity 。
9 }
10 // 省略部分代码
11 // If the top activity is the resumed one, nothing to do.
12 // 检查要启动的 Activity 组件是否等于当前被激活的 Activity 组件,如果等于,并且处于 RESUMED 状态,直接返回
13 if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
14 mStackSupervisor.allResumedActivitiesComplete()) {
15 // Make sure we have executed any pending transitions, since there
16 // should be nothing left to do at this point.
17 mWindowManager.executeAppTransition();
18 mNoAnimActivities.clear();
19 ActivityOptions.abort(options);
20 return false;
21 }
22
23 // If we are sleeping, and there is no resumed activity, and the top
24 // activity is paused, well that is the state we want.
25 // 检查要启动的 Activity 组件是否等于上一次被中止了的 Activity 组件,如果等于,
26 // 并且这时候系统正要进入关机或睡眠状态,则直接退出,启动毫无意义
27 if (mService.isSleepingOrShuttingDown()
28 && mLastPausedActivity == next
29 && mStackSupervisor.allPausedActivitiesComplete()) {
30 // Make sure we have executed any pending transitions, since there
31 // should be nothing left to do at this point.
32 mWindowManager.executeAppTransition();
33 mNoAnimActivities.clear();
34 ActivityOptions.abort(options);
35 return false;
36 }
37
38 // If we are currently pausing an activity, then don't do anything until that is done.
39 // 检查系统中止 Activity 组件是否完成,如果没有,则直接返回了,等待所有的 Activity 进入中止状态
40 if (!mStackSupervisor.allPausedActivitiesComplete()) {
41 return false;
42 }
43
44 // We need to start pausing the current activity so the top one can be resumed...
45 // Launcher 组件进入 onPause 状态
46 boolean dontWaitForPause = (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0;
47 boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);
48 if (mResumedActivity != null) {
49 // mResumedActivity 指向了 Launcher 组件,不为 null ,则中止 Launcher 组件
50 pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
51 }
52 // 省略部分代码
53
54 if (next.app != null && next.app.thread != null) {
55 // 待启动的 Activity 在新的进程中,app 变量为 null
56 } else {
57 // 创建一个新的应用程序进程
58 mStackSupervisor.startSpecificActivityLocked(next, true, true);
59 }
60
61 }
ActivityStack 类有三个成员变量:mResumedActivity
、mLastPausedActivity
、mPausingActivity
,它们的类型均为 ActivityRecord
,分别用来描述系统当前激活的 Activity 组件、上一次被中止的 Activity 组件,以及正在被中止的 Activity 组件。
而在resumeTopActivityInnerLocked
方法中,待其的 Activity 的 ActivityRecord 已经位于栈顶了,需要将它运行到 Resumed
状态,而在这之前需要判断满足很多条件,比如当前所有的 Activity 组件要处于 onPaused
状态,Launcher 组件要处于onPaused
状态,否则会直接 return 退出了。
当满足上面的条件时,最后就是判断待启动的 Activity 组件的应用程序进程是否创建,如果还没有,则通过startSpecificActivityLocked
创建一个应用程序进程来启动 Activity 组件。
涉及到的其他类
- ActivityStack
- ActivityStackSupervisor
- ActivityDisplay
- ActivityRecord
- ActivityInfo
- TaskRecord
参考
1、 Android 6.0 源码 2、《Android 系统源代码情景分析》 3、http://duanqz.github.io/2016-07-29-Activity-LaunchProcess-Part1
疑问
- Activity 的 堆栈 ActivityStack
原创文章,转载请注明来源: Android 6.0 Launcher 启动 Activity 过程源码分析(二)
相关文章
- Android 6.0 Launcher 启动 Activity 过程源码分析(一)
- 用 RxJava 封装回调方法 CallBack
- Android 硬件抽象层调用流程小结
- Kotlin 函数式编程与 Anko 构建布局实现原理分析
- Kotlin 使用 Anko 布局那些事
留言