当前位置: 首页 > news >正文

ActivityRecord、TaskRecord、ActivityStack、ActivityStackSupervisor、ProcessRecord

1 ActivityRecord

ActivityRecord 表示一个 Activity 实例的元数据,是 Activity 管理的最小单位。

ActivityManagerService - AMS/ActivityTaskManagerService - ATMS 负责管理系统中所有 Activity 的生命周期和状态。由于 Activity 运行在应用进程中,而 ActivityManagerService - AMS 运行在 system_server 进程中,二者处于不同的进程空间,为了能对 Activity 进行有效的管理,ActivityManagerService - AMS 为每个启动的 Activity 创建了一个 ActivityRecord 实例。这个实例就像是 Activity 在 ActivityManagerService - AMS/ActivityTaskManagerService - ATMS 中的“代言人”(或者说是应用层 Activity 组件在系统服务 AMS/ATMS 中的镜像表示),保存了 Activity 的关键信息:

  • 保存 Activity 的组件信息,如类名、包名;
  • 保存 Activity 的配置信息,如启动模式、主题、Intent 等;
  • 记录 Activity 的状态信息,如是否正在运行、暂停、销毁等;

ActivityRecord 伴随着 Activity 的启动而创建,也伴随着 Activity 的终止而销毁。

需要注意的是,Android 10 中引入了 ATMS,将 AMS 中的任务和活动栈管理的相关功能分离出来,由 ATMS 专门负责。

源码位置:frameworks/base/services/core/java/com/android/server/am/ActivityRecord.java

2 TaskRecord

Task 表示一个任务,即用户完成某个操作的一系列 Activity 的集合,TaskRecord 就是这个任务的记录。其职责有:

  • 维护 Activity 的后进先出栈,按顺序保存 ActivityRecord;
  • 处理 Activity 的入栈和出栈的逻辑;
  • 管理任务的属性(如 taskAffinity、前台/后台状态);

一个 TaskRecord 可以包括一个或多个 ActivityRecord,这种包含关系形成一个栈结构。ActivityRecord 代表具体的 Activity 实例在系统中的记录,而 TaskRecord 则是对一组相关 Activity 的集合管理。

例如,用户在一个应用中依次进行操作,从 Activity A 启动 Activity B,再到 Activity C,这三个 Activity 的 ActivityRecord 都会被添加到同一个 TaskRecord 中,并按照启动顺序入栈:
TaskRecord 和 ActivityRecord

栈顶的 ActivityRecord 处于可见状态,因为它是当前用户正在与之交互的界面,系统会根据栈的特性(先进后出)来处理 Activity 的显示和切换,当用户按下返回键时,栈顶的 ActivityRecord 会被出栈,下一个 ActivityRecord 成为栈顶并显示。

一般情况下,当启动应用的第一个 Activity 时,AMS/ATMS 会为其创建一个 TaskRecord 任务栈,这个任务栈成为该应用后续 Activity 启动和管理的基础。 比如,常见的社交应用,启动后首先展示在主界面的 Activity 会被放入新创建的任务栈中,之后在应用内进行其他界面跳转,新的 Activity 也会依次添加到这个任务栈中。

特殊情况下,当启动 singleTask 或 singleInstance 启动模式的 Activity,并且为该 Activity 指定了和包名不同的 taskAffinity 时,会为该 Activity 创建一个新的 TaskRecord。

singleTask 模式的特定是该 Activity 会在一个新的任务栈中启动(如果任务栈不存在的话),或者如果任务栈已存在,则会将任务栈移到前台并清除栈中该 Activity 之上的其他 Activity。singleInstance 除了具有 singleTask 的所有特性外,还加强了一点,那就是,具有此模式的 Activity 只能单独的位于一个栈中。

因此,一个 APP 应用中是可能有多个 TaskRecord 存在的。

每个 Activity 有一个 taskAffinity 属性,决定 Activity 属于那个任务栈,默认为应用包名,ActivityRecord 会记录这个属性。

源码位置:frameworks/base/services/core/java/com/android/server/am/TaskRecord.java

3 ActivityStack

ActivityStack 是一个栈结构,负责管理多个 TaskRecord 并控制它们的显示层级和生命周期。ActivityStack 内部通过 ArrayList<TaskRecord> 维护任务栈的列表。

ActivityStack 和 ActivityRecord

在多任务系统中,可能会存在多个 ActivityStack,每个栈对应不同的用户操作场景。 例如,在多窗口模式下,不同的窗口可能对应不同的 ActivityStack,每个栈中可以有各自的任务。ActivityStack 会根据任务的优先级和用户操作来决定哪个任务的 Activity 应该显示在前台。

源码位置:frameworks/base/services/core/java/com/android/server/am/ActivityStack.java

4 ActivityStackSupervisor

ActivityStackSupervisor 负责协调和管理所有的 ActivityStack,确保同一时刻只有一个获取到焦点(Focused)的 ActivityStack。 例如,当系统收到一个启动新的 Activity 的请求时,ActivityStackSupervisor 会根据当前的任务和栈的状态,决定将新的 Activity 放入到哪个 ActivityStack 的那个 TaskRecord 中。

ActivityStackSupervisor 和 ActivityStack

ActivityStackSupervisor 内部包含两个重要的 ActivityStack 对象,即 mHomeStack 和 mFocusedStack:

  • mHomeStack:管理 Launcher(主屏幕)的 ActivityStack,负责管理主屏幕的各种 Activity 和任务,确保用户在操作主屏幕时的流畅体验;

  • mFoucsedStack:代表当前获取焦点的 ActivityStack,只有该栈栈顶的 ActivityRecord 处于 RESUMED 状态,接收用户的输入;

非 Launcher Activity Stack 的创建:

当系统启动第一个 APP 时,会创建一个非 Launcher Activity Stack。 这个 ActivityStack 专门用于管理该 APP 所产生的 TaskRecord。随着应用的运行,应用内可能会启动多个不同的 Activity,这些 Activity 对应的 TaskRecord 会被添加到这个非 Launcher Activity Stack 中。不同的应用通常会有各自独立的 ActivityStack,以确保任务的隔离和管理的高效性。

ActivityManagerService - AMS/ActivityTaskManagerService - ATMS 和 ActivityStackSupervisor 的关系:

  • 单例特性/唯一性:AMS/ATMS 在整个系统中是单例存在的,即系统中只会有一个 AMS/ATMS 对象。 这是因为 AMS/ATMS 是系统中管理应用程序组件的核心服务,需要统一协调和管理系统中的所有操作,单例设计可以确保系统管理的一致性和高效性;
  • 初始化关联:在 AMS/ATMS 初始化的过程中,会创建一个唯一的 ActivityStackSupervisor 对象。 ActivityStackSupervisor 作为 ActivityStack 的管理者,与 AMS 紧密协作,共同完成对应用程序任务栈的管理。AMS/ATMS 负责接收应用程序的请求,如启动 Activity 等,然后将这些请求传递给 ActivityStackSupervisor,由 ActivityStackSupervisor 来具体处理任务栈的创建、切换和管理等操作;

源码位置:frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

5 ProcessRecord

ProcessRecord 是 Android 系统中用于记录进程相关的信息类。一个 ProcessRecord 对象代表着一个进程,它包含了该进程的各种信息,如进程名、进程 ID、应用程序的包名等,同时也维护着一个列表,用于存储属于这个进程的所有 ActivityRecord。 这意味着,当一个应用程序的多个 Activity 在同一个进程中运行时,它们都会被记录在对应的 ProcessRecord 中。

TaskRecord 表示任务栈(先进后出结构),运行在不同的 TaskRecord 中的 Activity 可能属于同一个 ProcessRecord。 这是因为一个进程中可以包含多个 Activity,而这些 Activity 可以根据不同的启动模式、taskAffinity 等属性被分配到不同的 TaskRecord 中。

ProcessRecord 和 ActivityRecord

跨任务共享进程的场景:

  • 默认情况: 同一应用的所有 Activity 默认运行在同一进程(除非现实配置 android:process 属性)。即使这些 Activity 被启动到不同任务中(通过 FLAG_ACTIVITY_NEW_TASK),它们仍然属于同一 ProcessRecord;
  • 多任务示例: 应用 A 的 MainActivity 启动 DetailActivity,并指定 FLAG_ACTIVITY_NEW_TASK,两者分属不同的 TaskRecord,但共享同一进程,故其 ProcessRecord 相同;
  • 跨进程特例: 若两个应用配置了相同的 android:process 且签名一致,其组件可能共享进程,此时不同任务的 Activity 可能属于同一 ProcessRecord

示例流程:

  • 用户启动应用 A 的 MainActivity,系统创建进程 P1以及对应的 ProcessRecord,并将 Activity 推入任务 T1;
  • 用户从 MainActivity 跳转至 SettingActivity,并指定 FLAG_ACTIVITY_NEW_TASK,系统创建新任务 T2,但 SettingActivity 仍运行在 P1 中,ProcessRecord 不变;
  • 若用户切换回 T1 的 MainActivity,系统仅需要切换任务栈,无需重启进程 P1;

6 关系

ActivityTaskManagerService - ATMS 和 ActivityManagerService - AMS 运行在 system_server 进程中。system_server 进程是 Android 系统的核心进程,它承载了众多关键的系统服务,除了 ATMS 和 AMS 外,还包括 WindowManagerService - WMS、PackageManagerService - PMS 等,这些服务共同协作,为整个 Android 系统的正常运行提供了基础支持。

system_server 进程是分阶段启动服务的,其中 SystemServer.startBootstrapServices() 方法负责初始化基础服务,如 AMS、ATMS(ATMS 负责管理 Activity 任务栈(如创建、销毁 Task),AMS 管理进程和组件的生命周期(如进程优先级、内存回收等))。

ATMS/AMS 对象在整个系统中都只会存在一个,这是通过单例模式来实现的。这种设计保证了系统中对 Activity 和相关组件的管理的一致性和唯一性。同样,在 ATMS/AMS 初始化的时候,会创建唯一的 ActivityStackSupervisor 对象。 ATMS/AMS 通过 ActivityStackSupervisor 来管理 Activity,其单例特性也有助于确保系统在处理 Activity 相关操作时的协调和统一。

ActivityStackSupervisor 是一个重要的管理类,它内部维护了多个 ActivityStack(如 mHomeStack、mFocusedStack 等),用于管理不同类型和状态的 Activity Stack。 ActivityStack 又包含了多个 TaskRecord,TaskRecord 中则存储了具体的 ActivityRecord。通过这样的层级结构,ATMS/AMS 能够有效得对 Activity 的生命周期、任务栈的关机等进行全方面的控制和调度。

在 Android 系统中,ActivityStack 与显示设备存在关联。多屏幕的 Android 设备中(支持同时使用多个物理或虚拟显示屏幕的 Android 设备),每个显示设备可以有自己的 ActivityStack 集合,这样就能针对不同显示设备分别管理 Activity 的显示和任务栈。

多屏幕的 Android 设备指的是:支持同时使用多个物理或虚拟显示屏幕的 Android 设备。这些屏幕可以是内置的(如折叠手机展开后的双屏)、外接的(如通过 HDMI 或 USB - C 连接的显示器),或是通过软件分屏功能划分的多个独立显示的区域:

  • 物理多屏幕设备:
    • 折叠屏手机:Samsung Galaxy Z Fold 系列,展开形成一个巨大的内屏,折叠时使用外屏;
    • 双屏设备:Microsoft Surface Duo,两块独立物理屏幕通过链接,可同时显示不同内容;
    • 外接显示器:通过 USB-C、HDMI 或无线头屏连接的扩展屏幕(如电视、显示器);
  • 虚拟多屏幕设备(分屏):
    • 软件分屏:Android 7+ 的分屏模式,将屏幕划分为上下或左右两个区域,分别运行不同的应用;

ActivityStack 的创建:

  • 系统启动过程中: ATMS/AMS 检测到 Launcher 的启动请求,通过 ActivityStackSupervisor 创建首个 ActivityStack(通常是 mHomdStack),用于管理 Launcher 相关的 Activity。此时系统中仅存在一个 ActivityStack,即 Launcher Stack;
  • 启动第一个非 Launcher 应用时: 通过 AMS 创建新的进程,通过 ActivityStackSupervisor 创建非 Launcher 的 ActivityStack,并将新创建的 ActivityRecord 会被添加到 ActivityStack 中;
  • 随着应用和多窗口的出现,还可能创建更多的 ActivityStack 来满足不同的管理请求。

总结:ActivityStack 是物理或虚拟现实设备在任务管理层的抽象,管理多个 TaskRecord;TaskRecord 是用户任务的逻辑载体,包含一组 ActivityRecord;每个 ActivityRecord 都必须找到宿主 TaskRecord,其归属的 ActivityStack 是由启动模式、显示设备状体以及系统策略共同决定的。

7 相关源码(Android 13)

7.1 ATMS 和 AMS 的初始化

在 system_server 进程启动时,会调用 SystemServer.startBootstrapServices 方法来启动系统服务,其中就包括 ATMS 和 AMS。

7.1.1 ATMS 的初始化

以下是 ATMS 初始化的时序图:

ATMS 初始化

相关源码:

// /frameworks/base/services/java/com/android/server/SystemServer.java
private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {...// Activity manager runs the show.traceBeginAndSlog("StartActivityManager");// TODO: Might need to move after migration to WM.ActivityTaskManagerService atm = mSystemServiceManager.startService(ActivityTaskManagerService.Lifecycle.class).getService();mActivityManagerService = ActivityManagerService.Lifecycle.startService(mSystemServiceManager, atm);mActivityManagerService.setSystemServiceManager(mSystemServiceManager);mActivityManagerService.setInstaller(installer);mWindowManagerGlobalLock = atm.getGlobalLock();traceEnd();...
}// /frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
private final ArrayList<SystemService> mServices = new ArrayList<SystemService>();public <T extends SystemService> T startService(Class<T> serviceClass) {try {final String name = serviceClass.getName();Slog.i(TAG, "Starting " + name);Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + name);// Create the service.if (!SystemService.class.isAssignableFrom(serviceClass)) {throw new RuntimeException("Failed to create " + name+ ": service must extend " + SystemService.class.getName());}final T service;try {Constructor<T> constructor = serviceClass.getConstructor(Context.class);service = constructor.newInstance(mContext);} catch (InstantiationException ex) {throw new RuntimeException("Failed to create service " + name+ ": service could not be instantiated", ex);} catch (IllegalAccessException ex) {throw new RuntimeException("Failed to create service " + name+ ": service must have a public constructor with a Context argument", ex);} catch (NoSuchMethodException ex) {throw new RuntimeException("Failed to create service " + name+ ": service must have a public constructor with a Context argument", ex);} catch (InvocationTargetException ex) {throw new RuntimeException("Failed to create service " + name+ ": service constructor threw an exception", ex);}startService(service);return service;} finally {Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);}
}public void startService(@NonNull final SystemService service) {// Register it.mServices.add(service);// Start it.long time = SystemClock.elapsedRealtime();try {service.onStart();} catch (RuntimeException ex) {throw new RuntimeException("Failed to start service " + service.getClass().getName()+ ": onStart threw an exception", ex);}warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
}// /frameworks/base/services/core/java/com/android/server/SystemService.java
public abstract class SystemService { }// /frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
public static final class Lifecycle extends SystemService {private final ActivityTaskManagerService mService;public Lifecycle(Context context) {super(context);mService = new ActivityTaskManagerService(context);}@Overridepublic void onStart() {publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);mService.start();}public ActivityTaskManagerService getService() {return mService;}
}
7.1.2 AMS 的初始化

以下是 AMS 初始化的时序图:

AMS

// /frameworks/base/services/java/com/android/server/SystemServer.java
private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {...// Activity manager runs the show.traceBeginAndSlog("StartActivityManager");// TODO: Might need to move after migration to WM.ActivityTaskManagerService atm = mSystemServiceManager.startService(ActivityTaskManagerService.Lifecycle.class).getService();mActivityManagerService = ActivityManagerService.Lifecycle.startService(mSystemServiceManager, atm);mActivityManagerService.setSystemServiceManager(mSystemServiceManager);mActivityManagerService.setInstaller(installer);mWindowManagerGlobalLock = atm.getGlobalLock();traceEnd();...
}// /frameworks/base/services/core/java/com/android/server/SystemService.java
public abstract class SystemService { }// /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public static final class Lifecycle extends SystemService {private final ActivityManagerService mService;private static ActivityTaskManagerService sAtm;public Lifecycle(Context context) {super(context);mService = new ActivityManagerService(context, sAtm);}public static ActivityManagerService startService(SystemServiceManager ssm, ActivityTaskManagerService atm) {sAtm = atm;return ssm.startService(ActivityManagerService.Lifecycle.class).getService();}@Overridepublic void onStart() {mService.start();}public ActivityManagerService getService() {return mService;}
}public ActivityTaskManagerService mActivityTaskManager;
public ActivityManagerService(Context systemContext, ActivityTaskManagerService atm) {...mActivityTaskManager = atm;mActivityTaskManager.initialize(mIntentFirewall, mPendingIntentController,DisplayThread.get().getLooper());...}// /frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
private final ArrayList<SystemService> mServices = new ArrayList<SystemService>();public <T extends SystemService> T startService(Class<T> serviceClass) {try {final String name = serviceClass.getName();Slog.i(TAG, "Starting " + name);Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + name);// Create the service.if (!SystemService.class.isAssignableFrom(serviceClass)) {throw new RuntimeException("Failed to create " + name+ ": service must extend " + SystemService.class.getName());}final T service;try {Constructor<T> constructor = serviceClass.getConstructor(Context.class);service = constructor.newInstance(mContext);} catch (InstantiationException ex) {throw new RuntimeException("Failed to create service " + name+ ": service could not be instantiated", ex);} catch (IllegalAccessException ex) {throw new RuntimeException("Failed to create service " + name+ ": service must have a public constructor with a Context argument", ex);} catch (NoSuchMethodException ex) {throw new RuntimeException("Failed to create service " + name+ ": service must have a public constructor with a Context argument", ex);} catch (InvocationTargetException ex) {throw new RuntimeException("Failed to create service " + name+ ": service constructor threw an exception", ex);}startService(service);return service;} finally {Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);}
}public void startService(@NonNull final SystemService service) {// Register it.mServices.add(service);// Start it.long time = SystemClock.elapsedRealtime();try {service.onStart();} catch (RuntimeException ex) {throw new RuntimeException("Failed to start service " + service.getClass().getName()+ ": onStart threw an exception", ex);}warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
}// /frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
ActivityStackSupervisor mStackSupervisor;
public void initialize(IntentFirewall intentFirewall, PendingIntentController intentController, Looper looper) {mStackSupervisor = createStackSupervisor();}protected ActivityStackSupervisor createStackSupervisor() {final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mH.getLooper());supervisor.initialize();return supervisor;
}
7.2 创建 ActivityStackSupervisor

以下是 ActivityStackSupervisor 初始化的时序图:

ActivityStackSupervisor

// /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public ActivityManagerService(Context systemContext, ActivityTaskManagerService atm) {...mActivityTaskManager.initialize(mIntentFirewall, mPendingIntentController,DisplayThread.get().getLooper());...
}// /frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
ActivityStackSupervisor mStackSupervisor;
public void initialize(IntentFirewall intentFirewall, PendingIntentController intentController, Looper looper) {....mStackSupervisor = createStackSupervisor();...
}protected ActivityStackSupervisor createStackSupervisor() {final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mH.getLooper());supervisor.initialize();return supervisor;
}
7.3 ActivityRecord、Task 的创建以及挂载

ActivityRecord 和 Task

7.3.1 ActivityRecord 的创建

ActivityRecord 通常在启动 Activity 的过程中被创建。当发起启动 Activity 的请求时,系统会先对请求进行一系列的检查和处理,然后创建 ActivityRecord 来记录这个即将启动的 Activity。

// /frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
int execute() {...res = executeRequest(mRequest);...
}private int executeRequest(Request request) {...final ActivityRecord r = new ActivityRecord.Builder(mService).setCaller(callerApp).setLaunchedFromPid(callingPid).setLaunchedFromUid(callingUid).setLaunchedFromPackage(callingPackage).setLaunchedFromFeature(callingFeatureId).setIntent(intent).setResolvedType(resolvedType).setActivityInfo(aInfo).setConfiguration(mService.getGlobalConfiguration()).setResultTo(resultRecord).setResultWho(resultWho).setRequestCode(requestCode).setComponentSpecified(request.componentSpecified).setRootVoiceInteraction(voiceSession != null).setActivityOptions(checkedOptions).setSourceRecord(sourceRecord).build();...LastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask, inTaskFragment, balCode, intentGrants);...
}

executeRequest 方法的核心是创建 ActivityRecord 实例并调用 startActivityUnchecked 方法。

7.3.2 Task 的创建和挂载

在 Android 13 中,TaskRecord 被 Task 取代,Task 承担了原本 TaskRecord 的大部分功能。

Task:任务调度的基本单元,管理一组 Activity 的生命周期和窗口模式,替代了早期版本中的 ActivityStack 和 TaskRecord。

// /frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, Task inTask, TaskFragment inTaskFragment, @BalCode int balCode, NeededUriGrants intentGrants) {...result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,startFlags, doResume, options, inTask, inTaskFragment, balCode, intentGrants);...
}int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,int startFlags, boolean doResume, ActivityOptions options, Task inTask,TaskFragment inTaskFragment, @BalCode int balCode,NeededUriGrants intentGrants) {...// 	查找可用的任务栈final Task reusedTask = getReusableTask();...// computeTargetTask() 用于获取启动 Activity 所在的任务栈// 如果 reusedTask 不为空,则使用 reusedTask 任务栈,否则寻找目标任务栈final Task targetTask = reusedTask != null ? reusedTask : computeTargetTask();// 若目标任务栈为空,则标记为需要使用新任务,需要创建新任务栈final boolean newTask = targetTask == null;...if (newTask) {// 创建一个新的任务栈final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)? mSourceRecord.getTask() : null;// 在 setNewTask 方法中 调用 addOrReparentStartingActivity 方法,将 Activity 放入新的任务栈中setNewTask(taskToAffiliate);} else if (mAddingToTask) {// 将 Activity 加入到已有的任务栈中addOrReparentStartingActivity(targetTask, "adding to task");}...mRootWindowContainer.resumeFocusedTasksTopActivities(mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);...
}private Task getReusableTask() {// If a target task is specified, try to reuse that oneif (mOptions != null && mOptions.getLaunchTaskId() != INVALID_TASK_ID) {Task launchTask = mRootWindowContainer.anyTaskForId(mOptions.getLaunchTaskId());if (launchTask != null) {return launchTask;}return null;}boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 &&(mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0)|| isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK);putIntoExistingTask &= mInTask == null && mStartActivity.resultTo == null;ActivityRecord intentActivity = null;if (putIntoExistingTask) {if (LAUNCH_SINGLE_INSTANCE == mLaunchMode) {intentActivity = mRootWindowContainer.findActivity(mIntent, mStartActivity.info, mStartActivity.isActivityTypeHome());} else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {intentActivity = mRootWindowContainer.findActivity(mIntent, mStartActivity.info, !(LAUNCH_SINGLE_TASK == mLaunchMode));} else {intentActivity =mRootWindowContainer.findTask(mStartActivity, mPreferredTaskDisplayArea);}}if (intentActivity != null && mLaunchMode == LAUNCH_SINGLE_INSTANCE_PER_TASK&& !intentActivity.getTask().getRootActivity().mActivityComponent.equals(mStartActivity.mActivityComponent)) {intentActivity = null;}if (intentActivity != null&& (mStartActivity.isActivityTypeHome() || intentActivity.isActivityTypeHome())&& intentActivity.getDisplayArea() != mPreferredTaskDisplayArea) {intentActivity = null;}return intentActivity != null ? intentActivity.getTask() : null;
}

startActivityInner 这个方法主要是处理与任务栈相关的逻辑,如果找到可用的任务栈就直接使用这个任务栈,如果找不到,则新建一个任务栈:

// /frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
/** Returns the leaf task where the target activity may be placed. */
private Task computeTargetTask() {if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask&& (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {// A new task should be created instead of using existing one.return null;} else if (mSourceRecord != null) {return mSourceRecord.getTask();} else if (mInTask != null) {// The task is specified from AppTaskImpl, so it may not be attached yet.if (!mInTask.isAttached()) {// Attach the task to display area. Ignore the returned root task (though // usually they are the same) because "target task" should be leaf task.getOrCreateRootTask(mStartActivity, mLaunchFlags, mInTask, mOptions);}return mInTask;} else {final Task rootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags,null /* task */, mOptions);final ActivityRecord top = rootTask.getTopNonFinishingActivity();if (top != null) {return top.getTask();} else {// Remove the root task if no activity in the root task.rootTask.removeIfPossible("computeTargetTask");}}return null;
}private Task getOrCreateRootTask(ActivityRecord r, int launchFlags, Task task,ActivityOptions aOptions) {final boolean onTop =(aOptions == null || !aOptions.getAvoidMoveToFront()) && !mLaunchTaskBehind;final Task sourceTask = mSourceRecord != null ? mSourceRecord.getTask() : null;return mRootWindowContainer.getOrCreateRootTask(r, aOptions, task, sourceTask, onTop,mLaunchParams, launchFlags);
}// /frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
Task getOrCreateRootTask(@Nullable ActivityRecord r, @Nullable ActivityOptions options,@Nullable Task candidateTask, boolean onTop) {return getOrCreateRootTask(r, options, candidateTask, null /* sourceTask */, onTop,null /* launchParams */, 0 /* launchFlags */);
}Task getOrCreateRootTask(@Nullable ActivityRecord r,@Nullable ActivityOptions options, @Nullable Task candidateTask,@Nullable Task sourceTask, boolean onTop,@Nullable LaunchParamsController.LaunchParams launchParams, int launchFlags) {...// Next preference goes to the TaskDisplayArea candidate from launchParams// or activity options.TaskDisplayArea taskDisplayArea = null;...final int activityType = resolveActivityType(r, options, candidateTask);if (taskDisplayArea != null) {if (canLaunchOnDisplay(r, taskDisplayArea.getDisplayId())) {return taskDisplayArea.getOrCreateRootTask(r, options, candidateTask,sourceTask, launchParams, launchFlags, activityType, onTop);} else {taskDisplayArea = null;}}...return taskDisplayArea.getOrCreateRootTask(r, options, candidateTask, sourceTask,launchParams, launchFlags, activityType, onTop);
}// /frameworks/base/services/core/java/com/android/server/wm/TaskDisplayArea.java
Task getOrCreateRootTask(@Nullable ActivityRecord r, @Nullable ActivityOptions options,@Nullable Task candidateTask, @Nullable Task sourceTask,@Nullable LaunchParams launchParams, int launchFlags, int activityType, boolean onTop) {int windowingMode = WINDOWING_MODE_UNDEFINED;if (launchParams != null) {// If launchParams isn't null, windowing mode is already resolved.windowingMode = launchParams.mWindowingMode;} else if (options != null) {// If launchParams is null and options isn't let's use the windowing mode in the// options.windowingMode = options.getLaunchWindowingMode();}// Validate that our desired windowingMode will work under the current conditions.// UNDEFINED windowing mode is a valid result and means that the new root task will // inherit it's display's windowing mode.windowingMode = validateWindowingMode(windowingMode, r, candidateTask);return getOrCreateRootTask(windowingMode, activityType, onTop, candidateTask, sourceTask, options, launchFlags);
}Task getOrCreateRootTask(int windowingMode, int activityType, boolean onTop,@Nullable Task candidateTask, @Nullable Task sourceTask,@Nullable ActivityOptions options, int launchFlags) {final int resolvedWindowingMode =windowingMode == WINDOWING_MODE_UNDEFINED ? getWindowingMode() : windowingMode;if (!alwaysCreateRootTask(resolvedWindowingMode, activityType)) {Task rootTask = getRootTask(resolvedWindowingMode, activityType);if (rootTask != null) {return rootTask;}} else if (candidateTask != null) {final int position = onTop ? POSITION_TOP : POSITION_BOTTOM;final Task launchParentTask = getLaunchRootTask(resolvedWindowingMode, activityType, options, sourceTask, launchFlags, candidateTask);if (launchParentTask != null) {if (candidateTask.getParent() == null) {launchParentTask.addChild(candidateTask, position);} else if (candidateTask.getParent() != launchParentTask) {candidateTask.reparent(launchParentTask, position);}} else if (candidateTask.getDisplayArea() != this|| candidateTask.getRootTask().mReparentLeafTaskIfRelaunch) {if (candidateTask.getParent() == null) {addChild(candidateTask, position);} else {candidateTask.reparent(this, onTop);}}if (windowingMode != WINDOWING_MODE_UNDEFINED && candidateTask.isRootTask()&& candidateTask.getWindowingMode() != windowingMode) {candidateTask.mTransitionController.collect(candidateTask);candidateTask.setWindowingMode(windowingMode);}return candidateTask.getRootTask();}// 创建 Taskreturn new Task.Builder(mAtmService).setWindowingMode(windowingMode).setActivityType(activityType).setOnTop(onTop).setParent(this).setSourceTask(sourceTask).setActivityOptions(options).setLaunchFlags(launchFlags).build();
}
7.3.3 AcitivityRecord 的挂载到 TaskRecord
// /frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
private void setNewTask(Task taskToAffiliate) {final boolean toTop = !mLaunchTaskBehind && !mAvoidMoveToFront;final Task task = mTargetRootTask.reuseOrCreateTask(mStartActivity.info, mIntent, mVoiceSession,mVoiceInteractor, toTop, mStartActivity, mSourceRecord, mOptions);task.mTransitionController.collectExistenceChange(task);// ActivityRecord 的挂载,将 Activity 放入新的任务栈中addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask");ProtoLog.v(WM_DEBUG_TASKS, "Starting new activity %s in new task %s",mStartActivity, mStartActivity.getTask());if (taskToAffiliate != null) {mStartActivity.setTaskToAffiliateWith(taskToAffiliate);}
}private void addOrReparentStartingActivity(@NonNull Task task, String reason) {TaskFragment newParent = task;if (mInTaskFragment != null) {int embeddingCheckResult = canEmbedActivity(mInTaskFragment, mStartActivity, task);if (embeddingCheckResult == EMBEDDING_ALLOWED) {newParent = mInTaskFragment;} else {// Start mStartActivity to task instead if it can't be embedded to mInTaskFragment.sendCanNotEmbedActivityError(mInTaskFragment, embeddingCheckResult);}} else {TaskFragment candidateTf = mAddingToTaskFragment != null ? mAddingToTaskFragment : null;if (candidateTf == null) {final ActivityRecord top = task.topRunningActivity(false /* focusableOnly */, false /* includingEmbeddedTask */);if (top != null) {candidateTf = top.getTaskFragment();}}if (candidateTf != null && candidateTf.isEmbedded()&& canEmbedActivity(candidateTf, mStartActivity, task) == EMBEDDING_ALLOWED) {// Use the embedded TaskFragment of the top activity as the new parent if the// activity can be embedded.newParent = candidateTf;}}if (mStartActivity.getTaskFragment() == null|| mStartActivity.getTaskFragment() == newParent) {newParent.addChild(mStartActivity, POSITION_TOP);} else {mStartActivity.reparent(newParent, newParent.getChildCount() /* top */, reason);}
}
7.4 ProcessRecord 的创建

判断是否需要创建新的进程:

// /frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
final ActivityTaskManagerService mService;
void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {// Is this activity's application already running?final WindowProcessController wpc =mService.getProcessController(r.processName, r.info.applicationInfo.uid);boolean knownToBeDead = false;if (wpc != null && wpc.hasThread()) {try {realStartActivityLocked(r, wpc, andResume, checkConfig);return;} catch (RemoteException e) {Slog.w(TAG, "Exception when starting activity "+ r.intent.getComponent().flattenToShortString(), e);}// If a dead object exception was thrown -- fall through to// restart the application.knownToBeDead = true;// Remove the process record so it won't be considered as alive.mService.mProcessNames.remove(wpc.mName, wpc.mUid);mService.mProcessMap.remove(wpc.getPid());}r.notifyUnknownVisibilityLaunchedForKeyguardTransition();final boolean isTop = andResume && r.isTopRunningActivity();mService.startProcessAsync(r, knownToBeDead, isTop,isTop ? HostingRecord.HOSTING_TYPE_TOP_ACTIVITY: HostingRecord.HOSTING_TYPE_ACTIVITY);
}
7.4.1 需要启动新的进程

ProcessRecord

// /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop,String hostingType) {try {if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "dispatchingStartProcess:"+ activity.processName);}// Post message to start process to avoid possible deadlock of calling into AMS // with the ATMS lock held.final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,mAmInternal, activity.processName, activity.info.applicationInfo, knownToBeDead, isTop, hostingType, activity.intent.getComponent());mH.sendMessage(m);} finally {Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);}
}// /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public final class LocalService extends ActivityManagerInternal {@Overridepublic void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead, boolean isTop, String hostingType, ComponentName hostingName) {try {if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "startProcess:"+ processName);}synchronized (ActivityManagerService.this) {// If the process is known as top app, set a hint so when the process is// started, the top priority can be applied immediately to avoid cpu // being preempted by other processes before attaching the process of // top app.startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,new HostingRecord(hostingType, hostingName, isTop),ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE, false /* allowWhileBooting */, false /* isolated */);}} finally {Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);}}
}final ProcessList mProcessList;
final ProcessRecord startProcessLocked(String processName,ApplicationInfo info, boolean knownToBeDead, int intentFlags,HostingRecord hostingRecord, boolean allowWhileBooting,boolean isolated, boolean keepIfLarge) {return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingRecord, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,null /* crashHandler */);
}// /frameworks/base/services/core/java/com/android/server/am/ProcessList.java
PcessRecord startProcessLocked(String processName, ApplicationInfo info,boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,int zygotePolicyFlags, boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean isSdkSandbox, int sdkSandboxUid, String sdkSandboxClientAppPackage, String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {long startTime = SystemClock.uptimeMillis();ProcessRecord app;if (!isolated) {app = getProcessRecordLocked(processName, info.uid);checkSlow(startTime, "startProcess: after getProcessRecord");if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {// If we are in the background, then check to see if this process// is bad.  If so, we will just silently fail.if (mService.mAppErrors.isBadProcess(processName, info.uid)) {if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid+ "/" + processName);return null;}} else {// When the user is explicitly starting a process, then clear its// crash count so that we won't make it bad until they see at// least one crash dialog again, and make the process good again// if it had been bad.if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid+ "/" + processName);mService.mAppErrors.resetProcessCrashTime(processName, info.uid);if (mService.mAppErrors.isBadProcess(processName, info.uid)) {EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,UserHandle.getUserId(info.uid), info.uid,info.processName);mService.mAppErrors.clearBadProcess(processName, info.uid);if (app != null) {app.mErrorState.setBad(false);}}}} else {// If this is an isolated process, it can't re-use an existing process.app = null;}// We don't have to do anything more if:// (1) There is an existing application record; and// (2) The caller doesn't think it is dead, OR there is no thread//     object attached to it so we know it couldn't have crashed; and// (3) There is a pid assigned to it, so it is either starting or//     already running.if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName+ " app=" + app + " knownToBeDead=" + knownToBeDead+ " thread=" + (app != null ? app.getThread() : null)+ " pid=" + (app != null ? app.getPid() : -1));ProcessRecord predecessor = null;if (app != null && app.getPid() > 0) {if ((!knownToBeDead && !app.isKilled()) || app.getThread() == null) {// We already have the app running, or are waiting for it to// come up (we have a pid but not yet its thread), so keep it.if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);// If this is a new package in the process, add the package to the listapp.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);checkSlow(startTime, "startProcess: done, added package to proc");return app;}// An application record is attached to a previous process,// clean it up now.if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App died: " + app);checkSlow(startTime, "startProcess: bad proc running, killing");ProcessList.killProcessGroup(app.uid, app.getPid());checkSlow(startTime, "startProcess: done killing old proc");if (!app.isKilled()) {// Throw a wtf if it's not killedSlog.wtf(TAG_PROCESSES, app.toString() + " is attached to a previous process");} else {Slog.w(TAG_PROCESSES, app.toString() + " is attached to a previous process");}// We are not going to re-use the ProcessRecord, as we haven't dealt with the // cleanup routine of it yet, but we'd set it as the predecessor of the new // process.predecessor = app;app = null;} else if (!isolated) {// This app may have been removed from process name maps, probably because we // killed it and did the cleanup before the actual death notification. Check the// dying processes.predecessor = mDyingProcesses.get(processName, info.uid);if (predecessor != null) {if (app != null) {app.mPredecessor = predecessor;predecessor.mSuccessor = app;}Slog.w(TAG_PROCESSES, predecessor.toString() + " is attached to a previous process "+ predecessor.getDyingPid());}}if (app == null) {checkSlow(startTime, "startProcess: creating new process record");app = newProcessRecordLocked(info, processName, isolated, isolatedUid, isSdkSandbox, sdkSandboxUid, sdkSandboxClientAppPackage,hostingRecord);if (app == null) {Slog.w(TAG, "Failed making new process record for "+ processName + "/" + info.uid + " isolated=" + isolated);return null;}app.mErrorState.setCrashHandler(crashHandler);app.setIsolatedEntryPoint(entryPoint);app.setIsolatedEntryPointArgs(entryPointArgs);if (predecessor != null) {app.mPredecessor = predecessor;predecessor.mSuccessor = app;}checkSlow(startTime, "startProcess: done creating new process record");} else {// If this is a new package in the process, add the package to the listapp.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);checkSlow(startTime, "startProcess: added package to existing proc");}// If the system is not ready yet, then hold off on starting this// process until it is.if (!mService.mProcessesReady&& !mService.isAllowedWhileBooting(info)&& !allowWhileBooting) {if (!mService.mProcessesOnHold.contains(app)) {mService.mProcessesOnHold.add(app);}if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,"System not ready, putting on hold: " + app);checkSlow(startTime, "startProcess: returning with proc on hold");return app;}checkSlow(startTime, "startProcess: stepping in to startProcess");final boolean success =startProcessLocked(app, hostingRecord, zygotePolicyFlags, abiOverride);checkSlow(startTime, "startProcess: done starting proc!");return success ? app : null;
}ProcessRecord getProcessRecordLocked(String processName, int uid) {if (uid == SYSTEM_UID) {// The system gets to run in any process.  If there are multiple// processes with the same uid, just pick the first (this// should never happen).SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);if (procs == null) return null;final int procCount = procs.size();for (int i = 0; i < procCount; i++) {final int procUid = procs.keyAt(i);if (!UserHandle.isCore(procUid) || !UserHandle.isSameUser(procUid, uid)) {// Don't use an app process or different user process for system // component.continue;}return procs.valueAt(i);}}return mProcessNames.get(processName, uid);
}ActivityManagerService mService = null;
private final MyProcessMap mProcessNames = new MyProcessMap();
final class MyProcessMap extends ProcessMap<ProcessRecord> {@Overridepublic ProcessRecord put(String name, int uid, ProcessRecord value) {final ProcessRecord r = super.put(name, uid, value);// ProcessRecord 和 WindowProcessController 建立联系mService.mAtmInternal.onProcessAdded(r.getWindowProcessController());return r;}@Overridepublic ProcessRecord remove(String name, int uid) {final ProcessRecord r = super.remove(name, uid);mService.mAtmInternal.onProcessRemoved(name, uid);return r;}
}ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,boolean isolated, int isolatedUid, boolean isSdkSandbox, int sdkSandboxUid,String sdkSandboxClientAppPackage, HostingRecord hostingRecord) {String proc = customProcess != null ? customProcess : info.processName;final int userId = UserHandle.getUserId(info.uid);int uid = info.uid;if (isSdkSandbox) {uid = sdkSandboxUid;}if (isolated) {if (isolatedUid == 0) {IsolatedUidRange uidRange = getOrCreateIsolatedUidRangeLocked(info, hostingRecord);if (uidRange == null) {return null;}uid = uidRange.allocateIsolatedUidLocked(userId);if (uid == -1) {return null;}} else {// Special case for startIsolatedProcess (internal only), where// the uid of the isolated process is specified by the caller.uid = isolatedUid;}mAppExitInfoTracker.mIsolatedUidRecords.addIsolatedUid(uid, info.uid);mService.getPackageManagerInternal().addIsolatedUid(uid, info.uid);// Register the isolated UID with this application so BatteryStats knows to// attribute resource usage to the application.//// NOTE: This is done here before addProcessNameLocked, which will tell // BatteryStats about the process state of the isolated UID *before* it is // registered with the owning application.mService.mBatteryStatsService.addIsolatedUid(uid, info.uid);FrameworkStatsLog.write(FrameworkStatsLog.ISOLATED_UID_CHANGED, info.uid, uid,FrameworkStatsLog.ISOLATED_UID_CHANGED__EVENT__CREATED);}final ProcessRecord r = new ProcessRecord(mService, info, proc, uid,sdkSandboxClientAppPackage,hostingRecord.getDefiningUid(), hostingRecord.getDefiningProcessName());final ProcessStateRecord state = r.mState;if (!isolated && !isSdkSandbox&& userId == UserHandle.USER_SYSTEM&& (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK&& (TextUtils.equals(proc, info.processName))) {// The system process is initialized to SCHED_GROUP_DEFAULT in init.rc.state.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_DEFAULT);state.setSetSchedGroup(ProcessList.SCHED_GROUP_DEFAULT);r.setPersistent(true);state.setMaxAdj(ProcessList.PERSISTENT_PROC_ADJ);}if (isolated && isolatedUid != 0) {// Special case for startIsolatedProcess (internal only) - assume the process// is required by the system server to prevent it being killed.state.setMaxAdj(ProcessList.PERSISTENT_SERVICE_ADJ);}addProcessNameLocked(r);return r;
}// /frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
final class LocalService extends ActivityTaskManagerInternal {public void onProcessAdded(WindowProcessController proc) {synchronized (mGlobalLockWithoutBoost) {mProcessNames.put(proc.mName, proc.mUid, proc);}} 
}// /frameworks/base/services/core/java/com/android/server/am/ProcessRecord.java
ProcessRecord(ActivityManagerService _service, ApplicationInfo _info, String _processName, int _uid, String _sdkSandboxClientAppPackage, int _definingUid, String _definingProcessName) {mService = _service;mProcLock = _service.mProcLock;info = _info;ProcessInfo procInfo = null;if (_service.mPackageManagerInt != null) {if (_definingUid > 0) {ArrayMap<String, ProcessInfo> processes =_service.mPackageManagerInt.getProcessesForUid(_definingUid);if (processes != null) procInfo = processes.get(_definingProcessName);} else {ArrayMap<String, ProcessInfo> processes =_service.mPackageManagerInt.getProcessesForUid(_uid);if (processes != null) procInfo = processes.get(_processName);}if (procInfo != null && procInfo.deniedPermissions == null&& procInfo.gwpAsanMode == ApplicationInfo.GWP_ASAN_DEFAULT&& procInfo.memtagMode == ApplicationInfo.MEMTAG_DEFAULT&& procInfo.nativeHeapZeroInitialized == ApplicationInfo.ZEROINIT_DEFAULT) {// If this process hasn't asked for permissions to be denied, or for a// non-default GwpAsan mode, or any other non-default setting, then we don't// care about it.procInfo = null;}}processInfo = procInfo;isolated = Process.isIsolated(_uid);isSdkSandbox = Process.isSdkSandboxUid(_uid);appZygote = (UserHandle.getAppId(_uid) >= Process.FIRST_APP_ZYGOTE_ISOLATED_UID&& UserHandle.getAppId(_uid) <= Process.LAST_APP_ZYGOTE_ISOLATED_UID);uid = _uid;userId = UserHandle.getUserId(_uid);processName = _processName;sdkSandboxClientAppPackage = _sdkSandboxClientAppPackage;if (isSdkSandbox) {sdkSandboxClientAppVolumeUuid = getClientInfoForSdkSandbox().volumeUuid;} else {sdkSandboxClientAppVolumeUuid = null;}mPersistent = false;mRemoved = false;mProfile = new ProcessProfileRecord(this);mServices = new ProcessServiceRecord(this);mProviders = new ProcessProviderRecord(this);mReceivers = new ProcessReceiverRecord(this);mErrorState = new ProcessErrorStateRecord(this);mState = new ProcessStateRecord(this);mOptRecord = new ProcessCachedOptimizerRecord(this);final long now = SystemClock.uptimeMillis();mProfile.init(now);mOptRecord.init(now);mState.init(now);mWindowProcessController = new WindowProcessController(mService.mActivityTaskManager, info, processName, uid, userId, this, this);mPkgList.put(_info.packageName, new ProcessStats.ProcessStateHolder(_info.longVersionCode));
}// /frameworks/base/services/core/java/com/android/server/wm/WindowProcessController.java
private volatile int mPid;
// user of process.
final int mUserId;
public WindowProcessController(@NonNull ActivityTaskManagerService atm,@NonNull ApplicationInfo info, String name, int uid, int userId, Object owner,@NonNull WindowProcessListener listener) {mInfo = info;mName = name;mUid = uid;mUserId = userId;mOwner = owner;mListener = listener;mAtm = atm;mBgLaunchController = new BackgroundLaunchProcessController(atm::hasActiveVisibleWindow, atm.getBackgroundActivityStartCallback());boolean isSysUiPackage = info.packageName.equals(mAtm.getSysUiServiceComponentLocked().getPackageName());if (isSysUiPackage || mUid == Process.SYSTEM_UID) {// This is a system owned process and should not use an activity config.// TODO(b/151161907): Remove after support for display-independent (raw) // SysUi configs.mIsActivityConfigOverrideAllowed = false;}onConfigurationChanged(atm.getGlobalConfiguration());mAtm.mPackageConfigPersister.updateConfigIfNeeded(this, mUserId, mInfo.packageName);
}public void setPid(int pid) {mPid = pid;
}public int getPid() {return mPid;
}

ProcessRecord:是进程元信息的管理者,记录进程的数据。如进程名、UID、启动参数、组件列表(Activity/Service 等)、进程状态(是否存活、是否缓存、OOM 优先级等)。在最新的 Android 源码中,不再与窗口系统交互,专注进程的生命周期和资源管理。

WindowProcessController:专注于窗口与进程的交互。如管理窗口可见性、焦点状态、动画,协调进程优先级(如调整 PROCESS_STATE_TOP 状态),处理和窗口管理器(WindowManagerService - WMS)的通信。通过持有进程标识符(PID/UID)间接关联进程信息。

7.4.2 不需要启动新进程

ActivityRecord 和 WindowProcessController

// /frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,boolean andResume, boolean checkConfig) throws RemoteException {...final Task task = r.getTask();final Task rootTask = task.getRootTask();...// The LaunchActivityItem also contains process configuration, so the configuration // change from WindowProcessController#setProcess can be deferred. The major reason // is that if the activity has FixedRotationAdjustments, it needs to be applied with // configuration.// In general, this reduces a binder transaction if process configuration is changed.proc.pauseConfigurationDispatch();r.startFreezingScreenLocked(proc, 0);// schedule launch ticks to collect information about slow apps.r.startLaunchTickingLocked();r.setProcess(proc);    ...return true;
}// /frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java
WindowProcessController app;  
private Task task;   
void setProcess(WindowProcessController proc) {app = proc;final ActivityRecord root = task != null ? task.getRootActivity() : null;if (root == this) {task.setRootProcess(proc);}proc.addActivityIfNeeded(this);mInputDispatchingTimeoutMillis = getInputDispatchingTimeoutMillisLocked(this);// Update the associated task fragment after setting the process, since it's // required for filtering to only report activities that belong to the same process.final TaskFragment tf = getTaskFragment();if (tf != null) {tf.sendTaskFragmentInfoChanged();}
}// /frameworks/base/services/core/java/com/android/server/wm/WindowProcessController.java
// The process of this application; 0 if none
/** All activities running in the process (exclude destroying). */
private final ArrayList<ActivityRecord> mActivities = new ArrayList<>();
void addActivityIfNeeded(ActivityRecord r) {// even if we already track this activity, note down that it has been launchedsetLastActivityLaunchTime(r.lastLaunchTime);if (mActivities.contains(r)) {return;}mActivities.add(r);mHasActivities = true;if (mInactiveActivities != null) {mInactiveActivities.remove(r);}updateActivityConfigurationListener();
}

参考

https://blog.csdn.net/qq_38679144/article/details/141995515
https://zhuanlan.zhihu.com/p/615272198

http://www.xdnf.cn/news/15499.html

相关文章:

  • 【工具】在Cursor/VS Code中配置Python调试环境的完整指南
  • VASP 6.4.1 Ubuntu系统编译安装手册
  • STM32学习2
  • LeadeRobot具身智能应用标杆:无人机X柔韧具身智能,空中精准作业游刃有余
  • Python 浮点数运算之谜:深入解析round(0.675, 2)等输出异常
  • 人工智能在WEB开发中的应用与实践
  • string函数具体事例
  • 数字化音乐教育软件 UI 设计的关键要点
  • 如何删除 Launchpad 中 Chrome 的图标
  • orcad csi 17.4 DRC规则设置及检查
  • 使用人工智能大模型kimi,如何免费制作PPT?
  • flutter app实现分辨率自适应的图片资源加载
  • 论文阅读:2023 arxiv Safe RLHF: Safe Reinforcement Learning from Human Feedback
  • Git-使用教程(新手向)
  • STM32CubeMX-H7-15-SPI通信协议读写W25Q64
  • 【springsecurity oauth2授权中心】简单案例跑通流程
  • 游戏APP如何抵御DDoS攻击与黑客勒索?实战防护全攻略
  • Java中的函数式编程详解
  • 【笔记】【C++】【基础语法】作用域(scope)、持续时间(duration)和链接(linkage)
  • OpenStack Yoga版安装笔记(22)Swift笔记20250418
  • 【Java面试系列】Spring Boot微服务架构下的分布式事务设计与实现详解 - 3-5年Java开发必备知识
  • 浏览器的存储机制 - Storage
  • 元宇宙概念兴起,B 端数字孪生迎来哪些新机遇?
  • leetcode-sql数据库面试题冲刺(高频SQL五十题)
  • 03、GPIO外设(三):标准库代码示例
  • 第11篇:Linux程序访问控制FPGA端HEX<四>
  • 服务器架构:SMP、NUMA、MPP及Docker优化指南
  • U盘实现——双盘符实现
  • GoogleCodeUtil.java
  • Next.js 技术详解:构建现代化 Web 应用的全栈框架