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

posted @ 2015-04-30 12:26  Simba.Chen  阅读(1737)  评论(0编辑  收藏  举报