AMS架构设计和源码分析
1 AMS简介
1.1 什么是AMS
AMS(ActivityManagerService)是系统的引导服务,应用进程的启动、切换和调度、四大组件的启动和管理都需要AMS的支持。
1.2 组件与AMS的通信方式
Activity 调用 AMS 代理对象 ActivityManagerProxy 通过 Bander 机制与 ActivityManagerNative 通信,ActivityManagerNative 继续调用其子类 ActivityManagerService 完成通信。为何要用 Bander 机制通信呢?因为 Activity 和 ActivityManagerProxy 都在 App进程,而ActivityManagerNative 和 ActivityManagerService 在 AMS进程(系统进程),这里涉及到两个进程之间的通信。
1.3 AMS体系化关系图
- IActivityManager 继承 IInterface
- Binder 继承 IBinder
- ActivityManagerService 继承 ActivityManagerNative
- ActivityManagerProxy 是抽象类 ActivityManagerNative 的内部类,ActivityManagerProxy 与抽象类 ActivityManagerNative 都实现IActivityManager
AMP(ActivityManagerProxy) 与 AMN(ActivityManagerNative) 实现了远程代理模式:AMP 和 AMN 是运行在两个进程的,AMP 是 Client 端,AMN 则是 Server 端,而 Server 端中具体的功能都是由 AMN 的子类 AMS 来实现的。AMN 又实现了 Binder 类,这样 AMP 和 AMS 就可以通过Binder来进行进程间通信。
ActivityManager是一个和 AMS 相关联的类,它主要对运行中的 Activity 进行管理,这些管理工作并不是由 ActivityManager 来处理的,而是交由 AMS 来处理,ActivityManager 中的方法会通过 AMN 的 getDefault 方法来得到 AMP ,通过 AMP 就可以和 AMN 进行通信,而 AMN 是一个抽象类,它会将功能交由它的子类 AMS 来处理,因此,AMP 就是 AMS 的代理类。除了ActivityManager,其他想要与 AMS 进行通信的类都需要通过 AMP,如下图所示:
2 AMS-startService源码分析(基于 Android 7.0 源码)
发起进程调用AMP-startService,经过binder驱动,最终调用系统进程AMS-startService,详细过程如下图:
一般我们在 Activity 中启动一个服务代码如下
startService(Intent(this,TestService::class.java))
查看startService的实现,发现调用的是 ContextWrapper 中的 startService 方法
public class ContextWrapper extends Context {
@UnsupportedAppUsage
Context mBase;
public ContextWrapper(Context base) {
mBase = base;
}
...
@Override
public ComponentName startService(Intent service) {
return mBase.startService(service);
}
...
}
ContextWrapper 中的 startService 方法调用 mBase
的 startService 方法,那么mBase
是什么呢,mBase
是同样继承 Context 的 ContextImpl类,可以看出这里用到了装饰者模式,调用方只需要关注ContextWrapper类,并不需要关注 ContextImpl 类的 startService 的具体实现,当ContextImpl 类的 startService 实现改动时对调用 ContextWrapper 中的 startService 的类是无感知的,并不需要改动调用方的代码。
继续跟进 ContextImpl 的 startService 代码
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, false, mUser);
}
其中又调用了 startServiceCommon(service, false, mUser)
private ComponentName startServiceCommon(Intent service, UserHandle user) {
try {
// 省略部分代码...
ComponentName cn = ActivityManagerNative.getDefault().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
getContentResolver()), getOpPackageName(), user.getIdentifier());
// 省略部分代码...
return cn;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
startServiceCommon 方法中会调用 AMN 的 getDefault 来获取 AMS 的代理类 AMP。接着调用了 AMP 的 startService 方法,先来查看 AMN 的getDefault方法
static public IActivityManager getDefault() {
return gDefault.get();
}
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
// 注释1
IBinder b = ServiceManager.getService("activity");
if (false) {
Log.v("ActivityManager", "default service binder = " + b);
}
// 注释2
IActivityManager am = asInterface(b);
if (false) {
Log.v("ActivityManager", "default service = " + am);
}
return am;
}+
};
}
getDefault 方法调用了gDefault
的 get 方法,gDefault
是一个Singleton类。注释1处得到名为activity
的 Service 引用,也就是IBinder 类型的 AMS 的引用。接着在注释2处将它封装成 AMP 类型对象,并将它保存到 gDefault 中,此后调用 AMN 的 getDefault 方法就会直接获得 AMS 的代理对象 AMP。asInterface 方法实现如下
static public IActivityManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
IActivityManager in =
(IActivityManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ActivityManagerProxy(obj);
}
我们继续看下 AMP 的构造方法
class ActivityManagerProxy implements IActivityManager {
public ActivityManagerProxy(IBinder remote) {
mRemote = remote;
}
// 省略部分代码...
}
AMP 的构造方法中将 AMS 的引用赋值给变量mRemote
,这样在 AMP 中就可以使用 AMS 了。其中 IActivityManager 是一个接口,AMN 和 AMP 都实现了这个接口,用于实现代理模式和 Binder 通信。接着继续看 AMP 的 startService 方法
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, String callingPackage, int userId) throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(caller != null ? caller.asBinder() : null);
service.writeToParcel(data, 0);
data.writeString(resolvedType);
data.writeString(callingPackage);
data.writeInt(userId);
// 注释1
mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);
reply.readException();
ComponentName res = ComponentName.readFromParcel(reply);
data.recycle();
reply.recycle();
return res;
}
首先会将传入的参数写入到 Parcel 类型的 data 中。在注释1处,通过IBinder 类型对象 mRemote(AMS的引用)向服务端的 AMS 发送一个START_SERVICE_TRANSACTION
类型的进程间通信请求。那么服务端AMS就会从 Binder 线程池中读取我们客户端发来的数据,最终会调用 AMN 的onTransact 方法
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
// 省略部分代码...
case START_SERVICE_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IBinder b = data.readStrongBinder();
IApplicationThread app = ApplicationThreadNative.asInterface(b);
Intent service = Intent.CREATOR.createFromParcel(data);
String resolvedType = data.readString();
String callingPackage = data.readString();
int userId = data.readInt();
// 注释1
ComponentName cn = startService(app, service, resolvedType, callingPackage, userId);
reply.writeNoException();
ComponentName.writeToParcel(cn, reply);
return true;
}
// 省略部分代码...
}
onTransact中注释1处会调用 AMS 的 startService 方法
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, String callingPackage, int userId)
throws TransactionTooLargeException {
// 省略部分代码...
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
"startService: " + service + " type=" + resolvedType);
synchronized(this) {
// 省略部分代码...
ComponentName res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid, callingPackage, userId);
Binder.restoreCallingIdentity(origId);
return res;
}
}
后面就是 AMS 处理 startService 的内容了,这里暂不讲解,有兴趣的同学可以继续深入。