ActivityManagerService简介
- ActivityManagerService(AMS)是android系统中一个非常重要的服务,主要用来管理四大组件Activity、ContentProvider、Service、Broadcast和内存进程调度。它就像一个大管家,管理着android系统中非常重要的组件,但它又不管理android中所有的重要对象,比如窗口相关的组件由WindowManagerService服务来管理,与通知相关的组件由NotificationManagerService服务来管理。
AMS的代码量巨大,总计20000+,这些代码只是其中一个类,它的实现还需要很多辅助类来共同完成。AMS是android三大核心功能之一,另外两个是WindowManagerService和View。尽管AMS的代码庞大,逻辑纷繁,但从所提供的功能来看,却没有看上去那么复杂。AMS所提供的主要功能包括以下几项:
- 统一调度各应用程序的Activity。应用程序要运行Activity,会首先报告给AMS,然后由AMS决定该Activity是否可以启动,如果可以,AMS再通知应用程序运行指定的Activity。换句话说,运行Activity是各应用程序的“内政”,AMS并不干预,但是AMS必须知道各应用程序都运行了哪些Activity。
- 内存管理。android官方声称,Activity退出后,其所在的进程并不会被立刻杀死,从而下次再启动该Activity时就能够提高启动速度。这些Activity只有当系统内存紧张时,才会被自动杀死,应用程序不用关心这个问题。而这些正是在AMS中完成的。
- 进程管理。AMS向外提供了查询系统正在运行的进程信息的API。
几个重要概念
AMS中定义了几个重要的数据类,分别用来保存进程(Process)、活动(Activity)、服务(Service)、广播(Broadcast)和任务(Task)等。
进程数据类ProcessRecord
表示一个进程信息,包括该进程里的Activity和Service等信息。
ActivityRecord数据类
表示单个Activity,它是堆栈中的基本单元。
ActivityRecord::Token
表示ActivityRecord中的内部静态类,继承与IApplicationToken.Stub,是一个Binder对象。它有两个作用:一是作为远程对象的本地句柄,用于进程间通信,二是作为关系映射中的unique ID。这个Token最后传递给应用程序客户端ActivityThread和服务WMS中。
AMS中的appToken在ActivityRecord的构造方法中被创建,创建好之后,它首先传递到WMS中构造一个AppWindowToken对象,这个传递过程由AMS通过调用WMS的addAppToken()方法来完成。接着appToken对象会传递到应用程序客户端ActivityThread中去构造ActivityClientRecord对象,而这个传递过程是AMS通过调用应用程序客户端ActivityThread的scheduleLauncherActivity()方法来完成的。最后,应用程序客户端还会通过调用addToDisplay()方法把这个对象传递到WMS中去,目的是去找到AMS传递到WMS时生成的APPWindowToken对象,验证当前窗口和Activity创建时的窗口是否一一对应。若ActivityRecord、ActivityClientRecord和APPWindowToken一一对应,则ActivityRecord代表Activity,APPWindowToken代表当前窗口,并且ActivityRecord和APPWindowToken有相同的Z轴位置,同时它们的Z轴还必须相同。如果Z轴不相同,界面的显示就会不一致。在android系统中,AMS和WMS都维护一个共同的Z轴位置,Z轴位置越大表示界面越显示在上面。
ServiceRecord数据类
表示单个Service,对应客户端的一个Service。
BroadcastRecord数据类
表示单个Broadcast,对应客户端一个Broadcast。
TaskRecord数据类
表示Task,里面有一个mActivities变量,这个变量ActivityRecord类型的ArrayList,而ArrayList就是按照Z轴位置的方式来存放ActivityRecord对象的。
ActivityStack
里面有一个mTaskHistory变量,这个变量是一个TaskRecord类型的ArrayList,其中,TaskRecord又间接管理着ActivityRecord。
ActivityStackSupervisor
主要管理ActivityStack,在android4.4版本以后,谷歌设计了两个ActivityStack,一个是Home stack,用来仿Launcher和SystemUI,id值为0,另一个是Application stack,用来仿其他应用程序,id值为非0。
ActivityStackSupervisor类有mStacks和mHomeStack这两个存放ActivityStack对象的ArrayList,其中mStacks在ActivityStackSupervisor的内部类ActivityDisplay中被定义。ActivityStack类的mTaskHistopry对象是一个存放TaskRecord对象的ArrayList。而TaskRecord类又有一个stack变量和mActivities变量,stack变量表示目前的ActivityStack,mActivities变量也是一个ArrayList,里面存放的就是ActivityRecord对象,对应到客户端,即存放的就是Activity,它们以Z轴的方式组织在一起,和WMS的窗口顺序一一对应。
Activity Manager
Activity Manager的组成分为以下几个部分:
服务代理
由ActivityManagerProxy实现,用于与Server端提供的系统服务进行进程间通信。
服务中枢
ActivityManagerNative继承自Binder并实现IActivityManager,它提供服务接口和Binder接口的相互转化功能,并在内部存储服务代理对象,并提供了getDefault()方法返回服务代理。
Client
由ActivityManager封装一部分服务接口供Client调用。ActivityManager内部通过调用ActivityManagerNative的getDefault()方法,可以得到一个ActivityManagerProxy对象的引用,进而通过该代理对象调用远程服务的方法。
Server
由ActivityManagerService实现,提供Server端的系统服务。
AMS的创建和初始化
ActivityManagerService(AMS)是android系统中一个非常重要的服务,它主要管理四大组件和进程内存的调度,它在SystemServer里的创建和启动,主要调用了一下几个方法:
- 12mActivityManagerService = mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class).getService();
- 1mActivityManagerService.setSystemProcess();
- 1mActivityManagerService.systemReady();
变量mSystemServiceManager是一个SystemServiceManager类型的对象,首先调用它的startService()方法创建AMS对象,接着调用这个AMS对象的setSystemProcess()方法来初始化AMS中的一些重要工作,最后调用systemReady()方法来判断AM是否启动和初始化成功。在android系统中,很多的核心服务都会提供systemReady()方法来判断它相应的服务是否启动和初始化成功,因为有些核心服务如果没有启动或者初始化失败,会严重影响系统的使用,如AMS,WMS等核心服务。而有些服务没有提供这个方法,比如MountService,因为MountService主要管理Sdcard这部分,如果这个服务没有启动或者初始化失败,只会影响sdcard,对系统的影响不是很大。
- 首先来看一下startService()方法创建AMS对象。
|
|
SystemServiceManager类的startService()方法创建了一个Lifecycle实例,然后返回,而在SystemServer类里通过这个返回的实例调用getService()方法就获得AMS对象。Lifecycle是AMS的内部类,在创建这个实例的时候,会调用它的构造方法。(由于AMS并没有继承SystemService,因此不能通过SystemServiceManager的startService直接启动它 )
|
|
Lifecycle的构造方法创建了一个AMS实例对象,而它的getService()方法会返回构造方法里创建的这个AMS实例对象。
先来看看AMS的构造函数
|
|
AMS的构造函数还是相对比较简单的,主要工作就是初始化一些变量。 接下来看看AMS的start()函数。
|
|
AMS的start函数比较简单,主要是:
①启动CPU监控线程。该线程将会开始统计不同进程使用CPU的情况。
②发布一些服务,如BatteryStatsService、AppOpsService(权限管理相关)和本地实现的继承ActivityManagerInternal的服务。
- 回到前面,接下来调用ActivityManagerService的setSystemProcess()方法。这个方法除了注册一些服务外,还将framework-res.apk的信息加入到SystemServer对应的LoadedApk中,同时构建SystemServer进程对应的ProcessRecord, 以将SystemServer纳入AMS的管理体系。
|
|
从上面的代码可以看出,AMS的setSystemProcess主要有四个主要的功能:
①通过Binder通信注册一些服务
②获取package名为“android”的应用的ApplicationInfo
③调用ActivityThread的installSystemApplicationInfo,将ApplicationInfo保存到SystemServer对应的ActivityThread中
④AMS进程管理相关的操作
- 最后,继续调用ActivityManagerService的systemReady()方法。
|
|
至此,ActivityManagerService的创建和它的核心方法的调用分析完毕。
AMS的作用
- 各应用与服务之间的通信桥梁,由于Android屏蔽了进程概念,无论是应用内部的Activity或Servcie,还是另一应用的Activity或Service,启动都要经过AMS。按道理,我在应用内部Start一个Activity,直接new出来就行了,但在Android里,不能这样做,必须绕个弯,通过AMS,再由ams进入应用本身来启动。这样一来,所有应用进程里的所有Activity和Service,都保存在AMS里,AMS成了一个真正大管家。
- 应用调用AMS,采用AMS提供的IActivityManager远程Binder接口。而AMS反调应用,则是应用提供的IApplicationThread远程Binder接口。当服务绑定之后,AMS反调应用提供的IServcieConnection远程Binder接口,来通知应用服务已经连接。
总结
回头看看整个过程,还是能比较清晰地将AMS的启动过程分为四步,如上图所示:
创建出SystemServer进程的Android运行环境
在这一部分,SystemServer进程主要创建出对应的ActivityThread和ContextImpl,构成Android运行环境。 AMS的后续工作依赖于SystemServer在此创建出的运行环境。
完成AMS的初始化和启动
在这一部分,单纯地调用AMS的构造函数和start函数,完成AMS的一些初始化工作。
将SystemServer进程纳入到AMS的管理体系中
AMS作为Java世界的进程管理和调度中心,要对所有Java进程一视同仁,因此SystemServer进程也必须被AMS管理。 在这个过程中,AMS加载了SystemServer中framework-res.apk的信息,并启动和注册了SettingsProvider.apk。
开始执行AMS启动完毕后才能进行的工作
系统中的一些服务和进程,必须等待AMS完成启动后,才能展开后续工作。 在这一部分,AMS通过调用systemReady函数,通知系统中的其它服务和进程,可以进行对应工作了。 在这个过程中,值得我们关注的是:Home Activity被启动了。当该Activity被加载完成后,最终会触发ACTION_BOOT_COMPLETED广播。