子Activity组件的startActivity逻辑

之前提到过三种不同的启动流程

不同启动流程

根据启动流程分为三种

  1. 通过Launcher点击app创建新进程,称为 根Activity组件的启动流程
  2. 点击app后进入app,在app中的startActivity操作,称之为 子Activity组件在进程内的启动流程
  3. 在app中,可能出现跳转到其他进程的app的Activity,称之为 子Activity组件在新进程中的启动流程

在Launcher流程中讲解了第一种,后面两种其实大致逻辑类似,因此放在一篇文章中来讲解

子Activity组件在进程内的启动流程

在该流程中,因为目标组件和原组件是同一个进程,因此就不需要创建新的进程了

在Launcher流程中的 startSpecificActivityLocked 函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
//获取即将要启动的Activity的所在的应用程序进程
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
r.getStack().setLaunchTime(r);

if (app != null && app.thread != null) {
try {
if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
|| !"android".equals(r.info.packageName)) {
app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
mService.mProcessStats);
}
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
}
}
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}

直接调用 realStartActivityLocked,流程和Launcher后续流程基本一致

栈处理

因为处于同一进程而且也没有使用 NEW_TASK 的flag,因此 AMS会在原ActivityStack中找到合适的位置添加新的组件,他们处于同一个 Task

子Activity组件在新进程中的启动流程

这个流程和第一个流程很类似,他同样也需要创建新的进程,唯一区别就是这个流程中,AMS不需要为新组件创建一个新任务,因为他们的 android:taskAffinity是一致的,所以他们放在同一个任务中

决定一个Activity是在新的进程中启动还是在原有的进程中启动的因素有两个

  1. 看这个Activity的process属性的值
  2. 看这个Activity所在的应用程序的uid

应用程序的UID是由系统分配的,而Activity的process属性值,是可以在AndroidManifest.xml文件中进行配置的,如果没有配置,它默认就为application标签的process属性值,如果application标签的process属性值也没有配置,那么,它们就默认为应用程序的package名。

在函数 startSpecificActivityLocked 中就是根据processName和uid在系统查找是否已有相应的进程存在,如果已经有了,就会调用realStartActivityLocked来直接启动Activity,否则的话,就要通过调用ActivityManagerService.startProcessLocked函数来创建一个新的进程,然后在新进程中启动这个Activity了。

任务

任务他比进程还要抽象和高级,他可以将运行在不同的Activity组合在一起,使得Android组件的重用性非常强