AMS的startActivity最终是调用的startActivityAndWait来处理启动请求的:
1 @Override
2 public final WaitResult startActivityAndWait(
3 IApplicationThread caller, //在多数情况下,一个Activity是由一个应用进程发起的,IApplicationThread是应用进程和AMS交互的通道,也可算是调用进程的标识
4 String callingPackage,//调用的包名,即发起启动请求的包名
5 Intent intent,
6 String resolvedType,
7 IBinder resultTo, //用于接收startActivityForResult的结果
8 String resultWho,
9 int requestCode,//这个是调用者来定义其意义,若值大于等于0,则AMS内部保存该值并通过onActivityResult返回调用者
10 int startFlags,
11 ProfilerInfo profilerInfo,//性能统计相关
12 Bundle options,
13 int userId//用户id
14 ) {
15 enforceNotIsolatedCaller("startActivityAndWait");
16 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
17 false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
18 WaitResult res = new WaitResult();//创建WaitResult对象用于保存处理结果
19 // TODO: Switch to user app stacks here.mStackSupervisor是ActivityStack类型
20 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
21 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
22 options, userId, null, null);
23 return res;
24 }
至此我们知道Activity是由ActivityStack来调度的,ActivityStack类是Activity调度的核心角色。这里关乎Android的task,back stack,ActivityStack 及launch mode的东西,是Android调度Activity及task的核心管理方法。ActivityStack有两个核心成员,我们通过一个表格来表明其意义。
ActivityRecord //Activity由ActivityRecord表示
---------------
-state: ActivityState //表示该Activity的状态(RESUMED.PAUSED等)
-app: ProcessRecord //指向该Activity所在的进程
-task: TaskRecord //指向该Activity所在的task
+stack: ActivityStack //指向管理此Activity的ActivityStack
TaskRecord //表示一个task
-------------
-taskId :int //此task的id编号
-intent: Intent
-numAcitivities:int //此task中的Activity数目
ActivityStack //Activity所处的栈
--------------
-mMainStack: boolean //表示此栈是否为主ActivityStack
-mHistory :ArrayList<ActivityRecord> //这里保存了所有的Task的ActivityRecord
我们从它们三者的关系能够看到,ActivityStack采用数组的方式保存所有Task的ActivityRecord,并且没有成员维护TaskRecord。然而ActivityStack是靠维护栈来调度Activity,所以这种管理一来少了TaskRecord的管理,开销少,二来弱化了Task的概念,结构不够清晰。
startActivityAndWait > startActivityMayWait
startActivityMayWait 包含了如下主要工作:
1. 通过PKMS 查找匹配改Intent的ActivityInfo。
1 // Collect information about the target of the Intent.
2 ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
3 profilerInfo, userId);
2. 获取调用者的pid 和 uid
1 synchronized (mService) {
2 final int realCallingPid = Binder.getCallingPid();
3 final int realCallingUid = Binder.getCallingUid();
4 int callingPid;
5 if (callingUid >= 0) {
6 callingPid = -1;
7 } else if (caller == null) {
8 callingPid = realCallingPid;
9 callingUid = realCallingUid;
10 } else {
11 callingPid = callingUid = -1;
12 }
3. 启动Activity的核心函数startActivityLocked .后面会说这个
1 int res = startActivityLocked(caller, intent, resolvedType, aInfo,
2 voiceSession, voiceInteractor, resultTo, resultWho,
3 requestCode, callingPid, callingUid, callingPackage,
4 realCallingPid, realCallingUid, startFlags, options,
5 componentSpecified, null, container, inTask);
4. 根据返回值做一些处理,此处在res返回成功时也需要等待是因为目标Activity要运行在一个新的应用进程中,就必须等待那个应用进程正常启动并处理相关请求。
1 if (outResult != null) {
2 outResult.result = res;
3 if (res == ActivityManager.START_SUCCESS) {
4 mWaitingActivityLaunched.add(outResult);
5 do {
6 try {
7 mService.wait(); //等待启动结果
8 } catch (InterruptedException e) {
9 }
10 } while (!outResult.timeout && outResult.who == null);
11 } else if
12 。。。。
startActivityMayWait > startActivityLocked
startActivityLocked分析
startActivityLocked主要工作包括:
1. 处理 sourceRecord(发起本次请求的Activity) 及 ResultRecord(接收处理结果的Activity),一般情况下两者是一样的。
1 ActivityRecord sourceRecord = null;
2 ActivityRecord resultRecord = null;
3 if (resultTo != null) {
4 sourceRecord = isInAnyStackLocked(resultTo);
5 if (DEBUG_RESULTS) Slog.v(
6 TAG, "Will send result to " + resultTo + " " + sourceRecord);
7 if (sourceRecord != null) {
8 if (requestCode >= 0 && !sourceRecord.finishing) {
9 resultRecord = sourceRecord;
10 }
11 }
12 }
2.处理app switch ,如果AMS当前禁止app switch,则只能把本次启动请求保存起来。
关于AMS禁止app switch,是考虑到当某些重要(例如设置账号等)Activity处于前台,不希望系统因用户操作之外的原因切换Activity而设立的机制。
3. 调用startActivityUncheckedLocked作后续处理
err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, true, options, inTask);
startActivityUncheckedLocked函数分析
startActivityUncheckedLocked的目的简单,就是为新创建的ActivityRecord找到一个合适的Task。
1.首先确定是否需要为新的Activity创建一个Task,即是否设置FLAG_ACTIVITY_NEW_TASK标志位,代码较多就不贴了。
2.创建一个新的TaskRecord,并调用startActivityLocked函数进行处理,在startActivityLocked函数中,把新的ActivityRecord添加到ActivityStack的mHistory数组里。最终调用resumeTopActivitiesLocked来启动Activity。resumeTopActivitiesLocke会判断mResumeActivity是否为空,当为空时会启动startSpecificActivityLocked函数来创建一个应用进程。在startSpecificActivityLocked中直接调用startProcessLocked函数来创建一个新的应用进程。
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
在startProcessLocked中代码较多,其主要工作是通过发送消息给Zygote以派生出一个应用进程,这个新的应用进程便启动起来了。接下来就是这个新的应用进程和此前需要启动的Activity绑定的一个过程了。