AMS的startActivity分析
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绑定的一个过程了。