AMS启动流程
这道题想考察什么?
学员对AMS是什么,它的启动方式,以及AMS的管理方式
考生应该如何回答
先从进程的角度分析AMS,然后再结合系统启动流程讲解AMS的启动过程,最后讲解AMS如何给App提供服务的。
1. AMS与ATMS 是什么
ActivityManagerService简称 AMS,在Android 10 之前,AMS主要负责对四大组件进行管理和调度,同时,AMS也对进程、电池、内存、权限等进行管理。但在Android 10开始,系统发现AMS要承载的事务太多,就将Activity的管理迁移到了ActivityTaskManagerService中,ActivityTaskManagerService也被缩写为ATMS。
AMS与ATMS都是SystemServer进程中的系统服务,他们并不是独立的进程,所以,他们的启动和管理全部都是在SystemServer进程中进行的。
2. ATMS&AMS的启动
由于AMS和ATMS的启动流程基本一致,这里就以ATMS为例,对他们的启动流程进行分析。
在SystemServer进程启动后会执行main函数,main函数里面会执行run方法,代码如下:
private void run() {
//...
try {
//1、进入ActivityThread的attch,初始化了Instrumentation、
//context和调用Application的onCreate
createSystemContext();
}
try {
//...
// 启动各种服务,包括AMS,ATMS等
startBootstrapServices();
startCoreServices();
startOtherServices();
}
}
上面的代码会调用三个函数 startBootstrapServices()、startCoreServices()、startOtherServices(),这三个函数分别用于启动各类系统服务的,其中AMS&ATMS的启动如下面的代码所示:
private void startBootstrapServices() {
//......
//1、启动ATMS服务
ActivityTaskManagerService atm = mSystemServiceManager.startService(
ActivityTaskManagerService.Lifecycle.class).getService();
//2、启动AMS服务
mActivityManagerService = ActivityManagerService.Lifecycle.startService(
mSystemServiceManager, atm);
//3、将SystemServiceManager设置给AMS
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
//3、将installer设置给AMS
mActivityManagerService.setInstaller(installer);
//4、初始化电源管理功能
mActivityManagerService.initPowerManagement();
//5、设置系统进程
mActivityManagerService.setSystemProcess();
//6、初始化看门狗
watchdog.init(mSystemContext, mActivityManagerService);
}
大家通过代码1 不难发现,ATMS并不是直接启动,而是SystemServiceManager通过 Lifecycle类来间接实现。 SystemServiceManager是一个辅助类,它用于辅助SystemServer进程启动和管理SystemServer进程中的各类服务Service。由于需要管理的服务非常多,所以SystemServiceManager是通过管理所有实现了SystemService接口的类的方式来统一的运用反射启动这些服务。Lifecycle 是 ATMS 里的静态内部类,静态内部类不依赖于外部类,它封装了ATMS对象,同时实现了SystemService接口。Lifecycle 构造方法调用时,会初始化内部成员变量 mService,即调用ATMS的构造方法,构造方法中会执行一些初始化操作。
下面我们分析一下SystemServiceManager,通过startService函数启动AMTS的流程。
public <T extends SystemService> T startService(Class<T> serviceClass) {
try {
final String name = serviceClass.getName();
...
final T service;
try {
Constructor<T> constructor = serviceClass.getConstructor(Context.class);
service = constructor.newInstance(mContext);
} catch (InstantiationException ex) {
...
}
startService(service);
return service;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
}
通过上面的代码我们不难发现,startService()方法内部是运用了反射获取到了serviceClass类的对象实例service,然后再调用startService(service)如下所示:
public void startService(@NonNull final SystemService service) {
// Register it.
mServices.add(service);
// Start it.
long time = SystemClock.elapsedRealtime();
try {
service.onStart(); //code1 统一执行服务的onStart函数
}
...
}
在上面代码中会执行到code1,通过code1会执行到 ATMS的Lifecycle中的 onStart函数,通过这个onStart函数会执行ATMS的启动。那么ATMS启动onStart的流程又是怎样的呢?
具体Lifecycle的代码如下:
public static final class Lifecycle extends SystemService {
private final ActivityTaskManagerService mService;
public Lifecycle(Context context) {
super(context);
mService = new ActivityTaskManagerService(context);
}
@Override
public void onStart() {
publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService); //code1
mService.start(); //code2 ATMS start()
}
@Override
public void onUnlockUser(int userId) {
synchronized (mService.getGlobalLock()) {
mService.mStackSupervisor.onUserUnlocked(userId);
}
}
@Override
public void onCleanupUser(int userId) {
synchronized (mService.getGlobalLock()) {
mService.mStackSupervisor.mLaunchParamsPersister.onCleanupUser(userId);
}
}
public ActivityTaskManagerService getService() {
return mService;
}
}
首先分析一下code1代码块,publishBinderService函数最终会执行到下面的代码:
ServiceManager.addService(name, service, allowIsolated, dumpPriority)
这就表面,ATMS将自己的binder 发布到了ServcieManager这个进程上面了,发布上去的目的是方便后期其他进程调用ATMS的服务,具体的逻辑大家可以在Binder相关的章节学会。
其次,分析一下code2,上面代码中onStart()函数执行实则是在执行ATMS的start函数,如下代码所示:
private void start() {
LocalServices.addService(ActivityTaskManagerInternal.class, mInternal);
}
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
public ActivityTaskManagerService(Context context) {
//保存先前SystemServer 创建的SystemContext,感觉这个也可以通过mSystemThread 获取
mContext = context;
mFactoryTest = FactoryTest.getMode();
mSystemThread = ActivityThread.currentActivityThread();// 获取 ActivityThread
mUiContext = mSystemThread.getSystemUiContext();// 获取 mUiContext
mLifecycleManager = new ClientLifecycleManager();
mInternal = new LocalService();
GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
GL_ES_VERSION_UNDEFINED);
mWindowOrganizerController = new WindowOrganizerController(this);
mTaskOrganizerController = mWindowOrganizerController.mTaskOrganizerController;
}
实际上,start函数就是在将ATMS的本地服务保存到LocalServices列表中,当然,ATMS的本地服务大家理解为就是ATMS的服务就好了。
小结
AMS&ATMS的启动流程进行小结:
首先,他们都是SystemServer进程中的服务,都是在SystemServer进程启动的时候进行启动;
其次,在他们启动的过程中,并不是直接自己启动的,而是由SystemServer进程通过SystemServiceManager对象进行统一的启动;
然后,ATMS&AMS 启动后会将自己的本地服务公布到LocalServices列表,将来进程内别的服务需要使用他们的时候可以去LocalServices中找到;
最后,ATMS&AMS 会将自己的binder 公布给ServiceManager进程,由这个进程去进程存储,方便后面其他进程获取AMS和ATMS的binder 代理。
3. ATMS与AMS的管理
ATMS与AMS的管理是非常典型的android系统对systemServer进程创建的各类服务管理案例。具体的逻辑我们进行如下的分析:
1)SystemServer进程会启动大概90多项的系统服务,为了能够更好的启动和管理这么多服务,那么SystemServer进程就需要依靠SystemServiceManager 的对象来协助管理。因此各项服务基本都是采用了如下的代码模板进行启动:
mSystemServiceManager.startService(ActivityTaskManagerService.Lifecycle.class)
具体的启动流程在上面的环节已经介绍。
2)SystemServiceManager并非直接去启动AMS等服务,而是采用启动这些服务的Lifecycle的方式,原因是什么呢?方便管理。其实,读者们你们细细想想,如果要启动一个服务,一般是不是需要先创建这个服务的对象,然后再进行这个对象的服务的启动,如果systemServer直接去操作这些服务,比如会出现非常多的样板代码。因此,systemServer就借助SystemServcieManager 去完成这个庞大的重复工作。当然,为了SystemServcieManager 更加内聚,于是就让每个服务都自动包含一个Lifeycle类,这个类里面会去创建自己的服务的对象,同时会启动服务。而且所有服务的LifeCycle都拓展了SystemService类,这样所有统一的操作都可以在SystemService基类中完成。具体的代码在上面的章节中有比较详细的介绍。
3)当AMS与ATMS等服务启动后,为了方便将服务提供给第三方使用,此时系统进行了下面的管理:
-
调用
LocalServices.addService(),将服务存储在SystemServer本地,以便SystemServer进程内部快速的实现服务的调用; -
调用
publishBinderService进而调用ServiceManager.addService函数,将服务的IBinder对象公布到ServiceManager进程,以便app进程通过ServiceManager调用这些服务。
4. 总结
AMS是由SystemServer进程通过SystemServiceManager启动并管理的一个对象,它和所有其他被SystemServer进程启动的服务一样并不是独立的进程,它只是一个服务。这个服务启动后会在SystemServer进程本地有一份存储,目的是方便当前进程共享该服务。同时AMS在ServiceManager进程也会进行发布,将自己的IBinder对象存在在SM中,方便其他第三方的进程去获取AMS的服务。
详细关注公众号:Android老皮
还能解锁 《Android十大板块文档》 ,让学习更贴近未来实战。已形成PDF版
内容如下:
1.Android车载应用开发系统学习指南(附项目实战)
2.Android Framework学习指南,助力成为系统级开发高手
3.2023最新Android中高级面试题汇总+解析,告别零offer
4.企业级Android音视频开发学习路线+项目实战(附源码)
5.Android Jetpack从入门到精通,构建高质量UI界面
6.Flutter技术解析与实战,跨平台首要之选
7.Kotlin从入门到实战,全方面提升架构基础
8.高级Android插件化与组件化(含实战教程和源码)
9.Android 性能优化实战+360°全方面性能调优
10.Android零基础入门到精通,高手进阶之路