【Android面试题】Android Framework核心面试题——AMS启动流程

307 阅读7分钟

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等服务启动后,为了方便将服务提供给第三方使用,此时系统进行了下面的管理:

  1. 调用LocalServices.addService(),将服务存储在SystemServer本地,以便SystemServer进程内部快速的实现服务的调用;

  2. 调用 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零基础入门到精通,高手进阶之路