从 Android-10.0 ATMS接管AMS对Activity的管理

近一个月上海疫情越来越严重,已居家办公三周。不得不感慨,平平安安就是福。

这里我基于Android 10.0画了一下抽象的站在整个Android Framework来看应用层的启动流程。

通过这几天对Framework层源码的学习过程中,习得一点经验。

  • 不可完全按照书本、博客等资料上说的来人云亦云。不同版本有差异,分析源码要亲力亲为。看别人怎么做的时候,自己也要动手。抱着怀疑、辩证的态度去看。
  • 源码体量太大,没法记住每个API函数调用链路,个人觉得是没有必要去强行记住。细节真的太多,主要还是以理解为主,抓核心原理就好。
  • 虽然不同版本的framework实现细节不一样,但它们在交互上的本质BinderAIDL没有变化,外部的架构也没有变化。

下面截取发现ATMS过程记录一下,上一次详细去读Activity启动流程当时Android版本发布到了7.0,转眼今年13.0也快出来了。

发现这个不同的点时,我当时正基于12.0sdk源码阅读,从Activity.startActivity(intent)跟踪下去到Instrumentation.execStartActivity(...)方法看到了ActivityTaskManager,有点懵逼了,和我之前理解的不太一样,不应该是AMS的代理对象么?带着这个疑问我开始就近翻阅不同版本的Instrumentation,发现从10.0开始变更。那么我们着重来看这两个版本的差异。

Android 9.0(28)

1
2
3
4
5
6
// Instrumentation.java execStartActivity(...)
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);

Android 10.0(29)

1
2
3
4
5
6
// Instrumentation.java execStartActivity(...)
int result = ActivityTaskManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);

这里我截取了最关键的调用处Instrumentation.execStartActivity(...)9.0委托给了ActivityManager,在10.0以后是ActivityTaskManager,我们需要关心的应该是getService()返回的对象。

Android 9.0(28)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// ActivityManager.java

public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}

private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};

Android 10.0(29)

1
2
3
4
5
6
7
8
9
10
11
12
13
// ActivityTaskManager.java

public static IActivityTaskManager getService() {
return IActivityTaskManagerSingleton.get();
}
private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
new Singleton<IActivityTaskManager>() {
@Override
protected IActivityTaskManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
return IActivityTaskManager.Stub.asInterface(b);
}
};

不难发现在getService()的调用上,设计思路没有任何变化,都是通过AIDL来获取远端的服务,只不过在10.0版本中获取到的接口变成了IActivityTaskManager,这里我们拿到的是AIDL中的Binder代理对象,我们翻过去看下Server端的实现类ActivityTaskManagerService.java

9.0的实现类是ActivityManagerService.java也就是我们经常提起的AMS服务。

通过翻阅工程,发现其实在10.0版本的源码中也存在ActivityManagerService.java这让人有点迷惑,为什么既有AMS又有ATMS

既然这样只好翻开大名鼎鼎的SystemServer.java来看看在Framework初始化各服务时到是怎么工作的?

Android 9.0(28)

1
2
3
4
5
6
// SystemServer.java

mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);

Android 10.0(29)

1
2
3
4
5
6
7
8
// SystemServer.java

ActivityTaskManagerService atm = mSystemServiceManager.startService(
ActivityTaskManagerService.Lifecycle.class).getService();
mActivityManagerService = ActivityManagerService.Lifecycle.startService(
mSystemServiceManager, atm);
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);

可以看到相比9.010.0版本中同时会把ATMSAMS都初始化,并把ATMS作为入参给了AMS

那么我们来看看在10.0之后的AMS会怎么处理。

Android 10.0(29)

1
2
3
4
5
6
7
8
9
// ActivityManagerService.java

public int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
// 委托给了 mActivityTaskManager 来处理
return mActivityTaskManager.startActivity(caller, callingPackage, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions);
}

这里发现在高版本中AMS中对于调度Activity相关的内容已转给ATMS来完成。

同时在ATMS内部对栈管理也发生了一些变化

  • 12.0 用的 ActivityTaskSupervisor
  • 10.0、9.0 用的 ActivityStackSupervisor
    来管理Activity栈,特别是10.0版本中从ActivityStackSupervisor删除了下面几个stack,集中由RootActivityContainer来管理,到了12.0调整为RootWindowContainer

Android 9.0(28)

1
2
3
4
// ActivityStackSupervisor.java
ActivityStack mHomeStack;
ActivityStack mFocusedStack;
private ActivityStack mLastFocusedStack;

Android 10.0(29)

1
2
// ActivityStackSupervisor.java
RootActivityContainer mRootActivityContainer;

Android 12.0(29)

1
2
// ActivityTaskSupervisor.java
RootWindowContainer mRootWindowContainer;

细节不展开了,整套流程还是很复杂,调用链路非常长。可参考下面的链接对 Android 11.0Activity启动分析,我对着12.0比了一下调用xxxStaskxxx()相关的函数都改成了xxxTasksxxx():
https://zhuanlan.zhihu.com/p/382133130

这里我更加关心一个问题为啥要改成这样?

个人觉得有两个方面:

  • 在名称上把ActivityManager改成ActivityTaskManager可能更符合外面对它的认知。
  • 直接改名,会造成兼容性问题。虽然Android官方可以在Framework层面将所有的调用处都替换成ATMS但对于应用层各种反射、Hook手段完成完成诸如插件化加载的事情可能会造成大面积失效。基于此不得不把原来的类保留。(向来sdk层的改动都是向前先兼容多个版本的,后面可能也会废弃)

不过这两个原因都只是我单方面猜测,不确定Google的开发者做这件事的时候是怎么思考的。

更正:

经过分析发现在Android 10.0版本中,ATMS被设计出来专门调度Activity生命周期。而AMS职责没有变,它范围更广泛,需要对四大组件的生命周期、进程进行管理。这么看我觉得这样做的好处是把ATMS的事情都拆了出来。

随缘打赏!