理解 ActivityManagerService

AMS 是 Android 中最核心的服务,主要负责系统中四大组件的启动、切换、调度及应用进程的管理和调度等工作,其职责与操作系统中的进程管理和调度模块相类似,因此它在 Android 中非常重要。

AMS 家族

之所以称为 AMS 家族,因为会有一些类来帮助 AMS 完成相关逻辑。

Android 7.0 和 Android 8.0 对于 AMS 相关部分处理有较大的区别。

Android 7.0 的 AMS 家族

ActivityManager 是一个和 AMS 相关联的类,它主要对运行中的 Activity 进行管理,这些管理工作实际是交由 AMS 来处理的。

ActivityManager 中的方法会通过 ActivityManagerNative(以后简称 AMN)的 getDefault 方法来得到 ActivityManagerProxy(以后简称 AMP),通过 AMP 就可以和 AMN 进行通信,而 AMN 是一个抽象类,它将功能交由它的子类 AMS 来处理,因此,AMP 就是 AMS 的代理类。

AMS 作为系统服务,很多 API 是不会暴露给 ActivityManager 的,因此 ActivityManager 并不算是 AMS 家族的一份子。

接下来以 Android 7.0 的 Activity 启动过程来举例,在 Activity 的启动过程中会调用 Instrumentation 的 execStartActivity 方法。Instrumentation.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
...
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
// 调用了 AMN 的 getDefault() 来获取 AMS 的代理类 AMP。
// 接着,调用了 AMP 的 startActivity()。
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}

首先查看 AMN 的 getDefault 方法。ActivityManagerNative.java

1
2
3
4
static public IActivityManager getDefault() {
// 调用了 gDefault 的 get()
return gDefault.get();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* gDefault 是一个 Singleton 类
*/
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
// 得到名为 “activity” 的 Service 引用,也就是 IBinder 类型的 AMS 的引用。
IBinder b = ServiceManager.getService("activity");
if (false) {
Log.v("ActivityManager", "default service binder = " + b);
}
// 将上面得到的引用封装成 AMP 类型对象,并将它保存到 gDefault 中,此后调用 AMN 的 getDefault 方法就会直接获得 AMS 的代理对象 AMP。
IActivityManager am = asInterface(b);
if (false) {
Log.v("ActivityManager", "default service = " + am);
}
return am;
}
};

1
2
3
4
5
6
7
8
9
10
11
12
13
14
static public IActivityManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
// IActivityManager 是一个接口,AMN 和 AMP 都实现了这个接口,用于实现代理模式和 Binder 通信。
// descriptor 的值为 android.app.IActivityManager
IActivityManager in = (IActivityManager)obj.queryLocalInterface(descriptor);
// 用来查询本地进程是否有 IActivityManager 接口的实现,如果有则返回。
if (in != null) {
return in;
}
// 如果没有则将 IBinder 类型的 AMS 引用封装成 AMP。
return new ActivityManagerProxy(obj);
}
1
2
3
4
5
6
7
8
9
10
11
12
class ActivityManagerProxy implements IActivityManager
{
/**
* AMP 的构造方法如下。
*/
public ActivityManagerProxy(IBinder remote)
{
// 将 AMS 的引用赋值给变量 mRemote,这样在 AMP 中就可以使用 AMS 了。
mRemote = remote;
}
...
}

再回到 Instrumentation 的 execStartActivity 方法,查看 AMP 的 startActivity(),AMP 是 AMN 的内部类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
...
// 将传入的参数写入到 Parcel 类型的 data 中。
data.writeInt(requestCode);
data.writeInt(startFlags);
...
// 通过 IBinder 类型对象 mRemote(AMS 的引用)向服务器端的 AMS 发送一个 START_ACTIVITY_TRANSACTION 类型的进程间通信请求。那么服务器端 AMS 就会从 Binder 线程池中读取客户端发来的数据,最终会调用 AMN 的 onTransact 方法。
mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
reply.readException();
int result = reply.readInt();
reply.recycle();
data.recycle();
return result;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
case START_ACTIVITY_TRANSACTION:
{
...
// 调用了 AMS 的 startActivity 方法
int result = startActivity(app, callingPackage, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
reply.writeNoException();
reply.writeInt(result);
return true;
}
...
}

AMS 的 startActivity 方法最后会返回 startActivityAsUser 方法。ActivityManagerService.java

1
2
3
4
5
6
7
8
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {

return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}

startActivityAsUser 方法最后会返回 ActivityStarter 的 startActivityMayWait 方法,这一调用过程已经脱离了 AMS 家族的范畴。

1
2
3
4
5
6
7
8
9
10
11
@Override
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
enforceNotIsolatedCaller("startActivity");

userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),userId, false, ALLOW_FULL_ONLY, "startActivity", null);
// TODO: Switch to user app stacks here.
return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
profilerInfo, null, null, bOptions, false, userId, null, null);
}

总结:

在 Activity 的启动过程中,提到了 AMP、AMN 和 AMS,它们共同组成了 AMS 家族的主要部分。

AMP 是 AMN 的内部类,它们都实现了 IActivityManager 接口,这样它们就可以实现代理模式,具体来讲是远程代理:

  • AMP 和 AMN 是运行在两个进程中的,AMP 是 Client 端,AMN 是 Server 端,而 Server 端中具体的功能都是由 AMN 的子类 AMS 来实现的,因此,AMP 就是 AMS 在 Client 端的代理类。
  • AMN 又实现了 Binder 类,这样 AMP 和 AMS 就可以通过 Binder 来进行进程间通信。
  • ActivityManager 通过 AMN 的 getDefault 方法得到 AMP,通过 AMP 就可以和 AMS 进行通信。
  • 除了 ActivityManager 以外,有些想要与 AMS 进行通信的类也需要通过 AMP。

Android 8.0 的 AMS 家族

接下来以 Android 8.0 版本的 Activity 启动过程来展示 AMS 家族与 Android 7.0 都有哪些不同。

在 Activity 的启动过程中会调用 Instrumentation 的 execStartActivity 方法。Instrumentation.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
...
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
// 实际上调用的是 AMS 的 execStartActivity 方法。
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}

ActivityManager 的 getService 方法。ActivityManager.java

1
2
3
4
public static IActivityManager getService() {
// getService 方法调用了 IActivityManagerSingleton 的 get()。
return IActivityManagerSingleton.get();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* IActivityManagerSingleton 是一个 Singleton 类。
*/
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
// 得到名为 “activity” 的 Service 引用(Context.ACTIVITY_SERVICE 的值为 “activity”),也就是 IBinder 类型的 AMS 引用。
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
// 将上面的引用转换成 IActivityManager 类型的对象,这段代码采用的是 AIDL,IActivityManager.java 类是由 AIDL 工具在编译时自动生成的,IActivityManager.aidl 文件路径为 frameworks/base/core/java/android/app/IActivityManager.aidl。
// 要实现进程间通信,服务器端也就是 AMS 只需要继承 IActivityManager.Stub 类并实现相应的方法就可以了。
// 采用 AIDL 后就不需要使用 AMS 的代理类 AMP 了,因此 Android 8.0 去掉了 AMP,代替它的是 IActivityManager ,它是 AMS 在本地的代理。
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};

总结:

对比 Android 7.0 的 AMS 家族,Android 8.0 的 AMS 家族要简单得多,ActivityManager 的 getService 方法会得到 IActivityManager,AMS 只需要继承 IActivityManager.Stub 类,就可以和 ActivityManager 实现进程间通信了。


AMS 的启动过程

AMS 的启动是在 SystemServer 进程中启动的。接下来从 SystemServer 的 main 方法开始:SystemServer.java

1
2
3
4
public static void main(String[] args) {
// main 方法只调用了 SystemServer 的 run 方法。
new SystemServer().run();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
private void run() {
try {
...
// 创建 Looper
Looper.prepareMainLooper();

// 加载了动态库 libandroid_servers.so
System.loadLibrary("android_servers");
performPendingShutdown();
// 创建系统的 Context
createSystemContext();
// 创建 SystemServiceManager,它会对系统的服务进行创建、启动和生命周期管理。
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
SystemServerInitThreadPool.get();
} finally {
traceEnd(); // InitBeforeStartServices
}

// Start services.
try {
traceBeginAndSlog("StartServices");
// 官方将系统服务分为 3 种类型,这些服务的父类都是 SystemService。
// 启动引导服务,此方法中用 SystemServiceManager 启动了 ActivityManagerService、PowerManagerService、PackageManagerService 等服务。
startBootstrapServices();
// 启动核心服务,此方法中启动了 DropBoxManagerService、BatteryService、UsageStatsService 和 WebViewUpdateService。
startCoreServices();
// 其它服务是一些非紧要和不需要立即启动的服务。
// 启动其它服务,此方法中启动了 CameraService、AlarmManagerService、VrManagerService 等服务。
startOtherServices();
SystemServerInitThreadPool.shutdown();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
traceEnd();
}
...
// Loop forever。
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}

接下来查看引导服务 AMS 是如何启动的,startBootstrapServices 方法如下。

1
2
3
4
5
6
7
8
9
10
11
private void startBootstrapServices() {
...
traceBeginAndSlog("StartActivityManager");
// 通过下面的两段代码,可以知道 mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class).getService() 实际上得到的就是 AMS 实例。
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
traceEnd();
...
}

调用了 SystemServiceManager 的 startService 方法,该方法的参数是 ActivityManagerService.Lifecycle.class。SystemServiceManager.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public void startService(@NonNull final SystemService service) {
// 传入的 SystemService 类型的 service 对象的值为 ActivityManagerService.Lifecycle.class。
// 将 service 对象添加到 ArrayList 类型的 mServices 中来完成注册。
mServices.add(service);
long time = System.currentTimeMillis();
try {
// 调用 service 的 onStart 方法来启动 service 对象。
service.onStart();
} catch (RuntimeException ex) {
throw new RuntimeException("Failed to start service " + service.getClass().getName()
+ ": onStart threw an exception", ex);
}
warnIfTooLong(System.currentTimeMillis() - time, service, "onStart");
}

接下来查看 ActivityManagerService 的 Lifecycle 类。ActivityManagerService.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static final class Lifecycle extends SystemService {
private final ActivityManagerService mService;

public Lifecycle(Context context) {
super(context);
// 在构造函数中创建了 AMS 的实例。
mService = new ActivityManagerService(context);
}

@Override
public void onStart() {
// 当调用 SystemService 类型的 service 的 onStart 方法时,实际上是调用了此处的 AMS 的 start 方法。
mService.start();
}

public ActivityManagerService getService() {
// 此方法会返回 AMS 实例。
return mService;
}
}

AMS 与应用程序进程

在 Zygote 的 Java 框架层中,会创建一个 Server 端的 Socket 用来等待 AMS 请求 Zygote 来创建新的应用程序进程。要启动一个应用程序,首先要保证这个应用程序所需要的应用程序进程已经存在。在启动应用程序时 AMS 会检查这个应用程序所需要的应用程序进程是否存在,不存在就会请求 Zygote 进程创建需要的应用程序进程。接下来以 Service 的启动过程为例,来分析 AMS 与应用程序进程的关系。

Service 在启动过程中会调用 ActivityServices 的 bringUpServiceLocked 方法。ActiveServices.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired)
throws TransactionTooLargeException {
...
// 得到 ServiceRecord 的 processName 的值并赋值给 procName,procName 用来描述 Service 想要在哪个进程运行,默认是当前进程,也可以在 AndroidManifest 文件中设置 android:process 属性来新开启一个进程运行 Service。
final String procName = r.processName;
String hostingType = "service";
ProcessRecord app;

if (!isolated) {
// 将 procName 和 Service 的 uid 传入到 AMS 的 getProcessRecordLocked 方法中,来查询是否存在一个与 Service 对应的 ProcessRecord 类型的对象 app,ProcessRecord 主要用来描述运行的应用程序进程的消息。
app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
+ " app=" + app);
// 如果运行 Service 的应用程序进程存在
if (app != null && app.thread != null) {
try {
app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
// 启动 Service
realStartServiceLocked(r, app, execInFg);
return null;
} catch (TransactionTooLargeException e) {
throw e;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting service " + r.shortName, e);
}

}
} else {
app = r.isolatedProc;
if (WebViewZygote.isMultiprocessEnabled()
&& r.serviceInfo.packageName.equals(WebViewZygote.getPackageName())) {
hostingType = "webview_service";
}
}
// 判断 Service 对应的 app 为 null 则说明用来运行 Service 的应用程序进程不存在。
if (app == null && !permissionsReviewRequired) {
// 调用 AMS 的 startProcessLocked 方法来创建对应的应用程序进程。
if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
hostingType, r.name, false, isolated, false)) == null) {
String msg = "Unable to launch app "
+ r.appInfo.packageName + "/"
+ r.appInfo.uid + " for service "
+ r.intent.getIntent() + ": process is bad";
Slog.w(TAG, msg);
bringDownServiceLocked(r);
return msg;
}
if (isolated) {
r.isolatedProc = app;
}
}

if (!mPendingServices.contains(r)) {
mPendingServices.add(r);
}

if (r.delayedStop) {
// Oh and hey we've already been asked to stop!
r.delayedStop = false;
if (r.startRequested) {
if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE,
"Applying delayed stop (in bring up): " + r);
stopServiceLocked(r);
}
}

return null;
}

总结:AMS 与应用程序进程的关系主要有以下两点:

  • 启动应用程序时 AMS 会检查这个应用程序需要的应用程序进程是否存在。
  • 如果需要的应用程序进程不存在,AMS 就会请求 Zygote 进程创建需要的应用程序进程。

AMS 重要的数据结构

AMS 涉及了很多数据结构,接下来分析一下 ActivityRecord、TaskRecord 和 ActivityStack,它们和应用开发关联较大,是 Activity 任务栈模型的基础。

解析 ActivityRecord

用来描述一个 Activity,内部记录了 Activity 的所有信息,是在启动 Activity 时被创建,具体是在 ActivityStarter 的 startActivity 方法中被创建的。

ActivityRecord 内部存储了 Activity 的所有信息,包括 AMS 的引用、AndroidManifes 节点信息、Activity 状态、Activity 资源信息和 Activity 进程相关信息等,需要注意的是其中含有该 ActivityRecord 所在的 TaskRecord,这就将 ActivityRecord 和 TaskRecord 关联在一起,它们是 Activity 任务栈模型的重要成员。

解析 TaskRecord

用来描述一个 Activity 任务栈。TaskRecord 的部分重要成员变量如下:

名称 类型 说明
taskId int 任务栈的唯一标识符
affinity String 任务栈的倾向性
intent Intent 启动这个任务栈的 Intent
mActivities ArrayList<ActivityRecord> 按照历史顺序排列的 Activity 记录
mStack ActivityStack 当前属性的 ActivityStack
mService ActivityManagerService AMS 的作用

TaskRecord 内部存储了任务栈的所有信息,需要注意的是其中含有 ActivityStack,也就是当前 Activity 任务栈所归属的 ActivityStack。

解析 ActivityStack

一个用来管理系统所有 Activity 的管理类,其内部维护了 Activity 的所有状态、特殊状态的 Activity 以及和 Activity 相关的列表等数据。由 ActivityStackSupervisor(在 AMS 的构造方法中被创建)来进行管理。ActivityManagerService.java

1
2
3
4
5
6
public ActivityManagerService(Context systemContext) {
...
// 在 createStackSupervisor 方法中创建了 ActivityStackSupervisor
mStackSupervisor = createStackSupervisor();
...
}
1
2
3
protected ActivityStackSupervisor createStackSupervisor() {
return new ActivityStackSupervisor(this, mHandler.getLooper());
}

ActivityStack 的实例类型

在 ActivityStackSupervisor 中有多种 ActivityStack 实例,并且提供了获取它们的 get 方法。ActivityStackSupervisor.java

1
2
3
4
5
6
7
8
9
10
public class ActivityStackSupervisor extends ConfigurationContainer implements DisplayListener {
...
// 用来存储 Launcher App 的所有 Activity。
ActivityStack mHomeStack;
// 表示当前正在接收输入或启动下一个 Activity 的所有 Activity。
ActivityStack mFocusedStack;
// 表示此前接收输入的所有 Activity。
private ActivityStack mLastFocusedStack;
...
}

ActivityState

在 ActivityState 中通过枚举存储了 Activity 的所有的状态,通过名称便可知道它们所代表的意义。ActivityStack.java

1
2
3
4
5
6
7
8
9
10
11
enum ActivityState {
INITIALIZING,
RESUMED,
PAUSING,
PAUSED,
STOPPING,
STOPPED,
FINISHING,
DESTROYING,
DESTROYED
}

应用 ActivityState 的场景会有很多,比如:ActivityManagerService.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* overridePendingTransition 方法用于设置 Activity 的切换动画
*/
@Override
public void overridePendingTransition(IBinder token, String packageName,
int enterAnim, int exitAnim) {
synchronized(this) {
ActivityRecord self = ActivityRecord.isInStackLocked(token);
if (self == null) {
return;
}

final long origId = Binder.clearCallingIdentity();
// 只有 ActivityState 为 RESUMED 状态或 PAUSING 状态时才会调用 WMS 类型的 mWindowManager 对象的 overridePendingAppTransition 方法来切换动画。
if (self.state == ActivityState.RESUMED
|| self.state == ActivityState.PAUSING) {
mWindowManager.overridePendingAppTransition(packageName,
enterAnim, exitAnim, null);
}

Binder.restoreCallingIdentity(origId);
}
}

特殊状态的 Activity

在 ActivityStack 中定义了一些特殊状态的 Activity,这些特殊的状态都是 ActivityRecord 类型的,ActivityRecord 用来记录一个 Activity 的所有信息。如下所示:ActivityStack.java

1
2
3
4
5
6
7
8
9
10
// 正在暂停的 Activity
ActivityRecord mPausingActivity = null;
// 上一个已经暂停的 Activity
ActivityRecord mLastPausedActivity = null;
// 最近一次没有历史记录的 Activity
ActivityRecord mLastNoHistoryActivity = null;
// 已经 Resume 的 Activity
ActivityRecord mResumedActivity = null;
// 传递给 convertToTranslucent 方法的最上层的 Activity
ActivityRecord mTranslucentActivityWaiting = null;

维护的 ArrayList

在 ActivityStack 中维护了很多 ArrayList,它们中的元素类型主要有 ActivityRecord 和 TaskRecord。ArrayList 中的元素类型及其说明如下:

ArrayList 元素类型 说明
mTaskHistory TaskRecord 所有没有被销毁的 Activity 任务栈
mLRUActivities ActivityRecord 正在运行的 Activity,列表中的第一个条目是最近最少使用的 Activity
mNoAnimActivities ActivityRecord 不考虑转换动画的 Activity
mValidateAppTokens TaskGroup 用于与窗口管理器验证应用令牌

ActivityStack 维护了元素类型为 TaskRecord 的列表,这样 ActivityStack 和 TaskRecord 就有了关联,Activity 任务栈存储在 ActivityStack 中。


Activity 栈管理

Activity 是放入在 Activity 任务栈中的,有了任务栈,系统和开发者就能够更好地应用和管理 Activity,来完成各种业务逻辑。

Activity 任务栈模型

Activity 任务栈是由多种数据结构共同组合而成的,上面提到的 ActivityRecord、TaskRecord 和 ActivityStack 就是 Activity 任务栈模型的重要组成部分。

ActivityRecord 用来记录一个 Activity 的所有信息,TaskRecord 中包含了一个或多个 ActivityRecord,TaskRecord 用来表示 Activity 的任务栈,用来管理栈中的 ActivityRecord,ActivityStack 又包含了一个或多个 TaskRecord,它是 TaskRecord 的管理者。

Activity 栈管理就是建立在 Activity 任务栈模型之上的,有了栈管理,可以对应用程序进行操作,应用可以复用自身应用中以及其他应用的 Activity,节省了资源。比如使用一款社交应用,这个应用的联系人详情界面提供了联系人的邮箱,当点击邮箱时会跳到发送邮件的界面。

社交应用和系统 E-mail 中的 Activity 是处于不同应用程序进程的,而有了栈管理,就可以把发送邮件界面放到社交应用中详情界面所在栈的栈顶,来做到跨进程操作。为了更灵活地进行栈管理,Android 系统提供了很多配置,包括 Launch Mode、Intent 的 FLAG 和 taskAffinity 等。


备注

注:基于 Android 8.0 版本源码分析

参考资料:
Android 进阶解密

单词音标: