在前面多篇文章中,都有提到ActivityManagerService,它是在系统启动时加载的一个服务线程,运行于system_server进程中,主要负责管理系统中的Activity和Service,那么,ActivityManagerService是怎么管理和维护这些Activity和Service的呢?这里的Service,指的是Activity应用里的Service。在看本篇文章之间,请先参阅《Android
进阶 - 进阶启动分析》,《Android 进阶 - Activity应用启动分析》,《Android 进阶 -
Activity服务启动分析》几篇文章,这样感觉会更直观。
1. 接口图
由于ActivityManagerService服务与Activity应用不在同一进程,之间的通讯都是采用Binder通讯,为了更好的理解ActivityManagerService是如何管理Activity和Service,又是如何与Activity和Service通讯的,我们先来看看组件图:
由上图可看出,无论是Activity应用还是Activity Service都是运行在ActivityThread里,左边是服务调用端,右边是服务的服务端,中间为ActivityManagerService服务端。
引出的几个接口都是基于Binder的远程通讯进接口,有了这几个接口,Activity应用就可以和ActivityManagerService(以下简称ams)相互通讯了。
2. 通信流程简介
2.1 Activity调用ams服务
ams属于系统服务,IActivityManager可以通过ServiceManager.getSystemService("activity");获取,详见ActivityManagerNative.getDefault()的代码。这个调用过程相对简单,凡是遇到ActivityManagerNative.getDefault().xxx()的代码,都是走的IActivityManager的远程接口,调用ams中的对应的接口。
2.2 ams调用Activity
在Activity应用启动之后,会创建ApplicationThread服务端,在调用ams的attachApplication接口时,会传入ApplicationThread对象,经由Binder进入ams后,此接口变为IApplicationThread远程接口,ams会将此变量与ams内部保存的app绑定在一起,建立起绑定之后,ams就可以通过app.thread反向调用Activity应用中提供的服务。
2.3 ams通知Activity服务
当Activity服务绑定成功之后,ams通过IServiceConnection远程接口,通知Activity客户端,服务已经绑定,并且会传回IXXXService远程接口对象,并经由ServiceConnect.onServiceConnected传给Activity。IServiceConnection是Activity客户端在bindService时,生成的一个LoadedApk.ServiceDispatch.InnerConnection对象,经由Binder传入到ams后,变为IServiceConnection远程接口,并保存ams的ActivityRecord列表中。
同理,当服务断开绑定后,也是通过IServiceConnection,通知Activity客户端,连接已经断开。
2.4 Activity应用调用Activity服务
当Activity应用接收到ServiceConnection.onServiceConnected事件后,但拿到XXXService服务端的远程接口IXXXService,Activity应用可以通过此远程接口,访问Activity服务中提供的服务。
3. ams的管理功能
从前面的介绍可以看出,ams就是Android系统中各类Activity和Service的通讯桥梁和大管家,ams中保存有所有的进程记录,Activity记录,Service记录等。
在ams里,有如下成员变量:
- mPidsSelfLocked:这是一个根据进程id(pid)保存的ProcessRecord数组,当有新进程创建时,会往mPidsSelfLocked里put一个进程记录ProcessRecord,并与pid关联,这样,以后可以通过pid来从此数组中获取进程的详细信息。
- mProcessNames:这是根据进程名称保存的ProcessRecord数组,当新进程创建时,会往mProcessNames里put一个进程记录ProcessRecord,并与进程名称关联,以后可以通过进程名称来获取进程信息。
- mIsolatedProcesses:隔离的进程列表,isolated进程是一个特殊进程,没有用户权限,只能API接口与其通讯。在Android Service中,如果isolated=true,即表示该服务为隔离的进程。
- mProcessesOnHold:暂时挂起的进程列表,这些进程因尝试在系统启动(system ready)完成之前启动,而被暂时挂起,当系统启动完成之后,会启动该列表中的进程。
- mPersistentStartingProcesses:持久化核心进程列表,这些进程免受out-of-memory killer的影响,不会被kill掉。当一个应用的android:persistent="true"时,该应用就升级为核心进程。
- mRemovedProcesses:被移除的进程列表。
- mLruProcesses:当前正在运行的进程信息列表。上面的进程信息列表,都不一定表示列表时的进程都在运行,此成员可以得出正在运行的进程列表。
- mProcessesToGc:当前已被通知清理内存的进程列表,和Android内存回收机制相关。
- mPendingPssProcesses:正在请求获取PSS Data的进程列表,和Android内存机制相关。
- mHomeProcess: 主屏幕应用进程
- mPreviousProcess:上一个进程
上面是与进程信息管理相关的成员,最常用到的就是mPidsSelfLocked和mProcessNames。这些信息都与ProcessRecord相关,ProcessRecord即进程记录,记录着一个进程的详细信息。ProcessRecord的成员非常多,这里挑选几个关键的成员说明:
- pid:进程ID
- thread:与进程相关联的应用远程IBinder接口(IApplicationThread),是ams与应用进程通讯的桥梁,ams可以通过此接口访问应用的服务功能。此接口在应用进程创建之后,通过ams.attachApplication,保存到ams的ProcessRecord中。
- activities:应用的Activity列表,所有此应用里启动的Activity,都保存在该列表中,列表中的对象为ActivityRecord。
- services:应用的Service列表,所有 此应用里启动的Service,都保存在该列表中,列表中的对象为ServcieRecord。
- executingServices:正在运行的服务列表,列表中的对象为ServiceRecord。
- connections:所有此应用保持的连接(包含:IServiceConnection)列表,这个连接列表是Activity 客户端绑定服务时创建的,当服务绑定成功之后,要通过IServiceConnection,将onServiceConnected事件发送至Activity客户端。
- receivers:此应用所有注册的receiver列表,列表中的对象为ReceiverList。
- pubProviders:此应用所有发布的ContentProvider列表。
- conProviders:此应用正在使用的ContentProvider列表。
- pkgList:此应用正在运行的package列表。
上面只简单介绍一些常用的信息,其他信息请自行研究源码。
4. ams的作用
简言之,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接口,来通知应用服务已经连接。IApplicationThread和IServiceConnection都不是Android Service的接口,由此可以看出,Binder是进程间通讯用的,并不一定是服务程序独有的,这将在后面的文章详细介绍。