浅析ServiceManager

通常客户端四大组件的交互少不了和AMS、PMS等系统服务的通信,客户端拿到AMS的远程Binder引用转换成客户端能够使用的代理,然后就可以和AMS通信了,但是这个远程Binder引用是怎么来的?

Client_ServiceManager_AMS

启动Activity

以启动Activity为例,调用startActivity启动Activity,然后调用Instrumentation.execStartActivity,

1
2
3
4
5
6
7
8
9
public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread)contextThread;
try {
int result = ActivityManager.getService().startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,requestCode, 0, null, options);
}
return null;
}

ActivityManager.getService(),

1
2
3
4
5
6
7
8
9
10
public static IActivityManager getService() { return IActivityManagerSingleton.get();}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};

可以看到调用ServiceManager.getService(Context.ACTIVITY_SERVICE)获取AMS的远程Binder引用,然后通过asInterface转换成客户端能够使用的本地代理。类似的,PowerManagerService、AlarmManagerService、BluetoothService也都是这样先获取远程Binder引用再通过asInterface转换成本地代理。ServiceManager类似远程服务解析器,传入字符串即可拿到对于服务的远程引用。

创建&添加服务

搜索源代码之后,在SystemServer.main()中执行run()时,SystemServiceManager完成了众多系统服务的创建并添加到ServiceManager的。SystemServer是系统进程,是Zygote第一个创建的进程,系统服务均允许在SystemServer进程中,和AMS、WMS等的Binder通信也是和这个进程在通信。
路径:/frameworks/base/services/java/com/android/server/SystemServer.java

首先服务需继承SystemService抽象类并实现onStart()方法,然后SystemServiceManager调用<T extends SystemService> T startService(Class<T> serviceClass)反射构造服务实例,再调用重载方法startService(SystemService service)调用实例的onStart()方法,最终调用ServiceManager.addService(Context.ALARM_SERVICE,service)添加服务。

以AlarmManagerService为例,SystemServiceManager反射创建AlarmManagerService实例再调用其onStart()方法,onStart()publishBinderService(Context.ALARM_SERVICE,mService)ServiceManager.addService(Context.ALARM_SERVICE,service)。最终AlarmManagerService创建完成并添加到ServiceManager,在客户端AlarmManager的底层调用均是AlarmManagerService的本地代理完成,最终通过Binder驱动完成和AlarmManagerService的通信。
类似的,AMS的创建是依托内部类Lifecycle完成创建并添加到ServiceManager中。

ServiceManager

Java层ServiceManager:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

public final class ServiceManager {
private static IServiceManager sServiceManager;
private static HashMap<String, IBinder> sCache = new HashMap<String, IBinder>();

private static IServiceManager getIServiceManager() {
if (sServiceManager != null) { return sServiceManager; }
// Find the service manager
sServiceManager = ServiceManagerNative.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
return sServiceManager;
}

public static IBinder getService(String name) {
try {
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
return Binder.allowBlocking(getIServiceManager().getService(name));
}
} catch (RemoteException e) {
}
return null;
}

public static IBinder getServiceOrThrow(String name) throws ServiceNotFoundException {
final IBinder binder = getService(name);
if (binder != null) {
return binder;
} else {
throw new ServiceNotFoundException(name);
}
}

public static void addService(String name, IBinder service) {
try {
getIServiceManager().addService(name, service, false);
} catch (RemoteException e) {
}
}

public static void addService(String name, IBinder service, boolean allowIsolated) {
try {
getIServiceManager().addService(name, service, allowIsolated);
} catch (RemoteException e) {
}
}

public static IBinder checkService(String name) {
try {
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
return Binder.allowBlocking(getIServiceManager().checkService(name));
}
} catch (RemoteException e) {
return null;
}
}

public static String[] listServices() {
try {
return getIServiceManager().listServices();
} catch (RemoteException e) {
return null;
}
}

public static void initServiceCache(Map<String, IBinder> cache) {
if (sCache.size() != 0) {
throw new IllegalStateException("setServiceCache may only be called once");
}
sCache.putAll(cache);
}
}

键值对String和IBinder类型的HashMap,使用字符串存取IBinder引用;
静态方法addServicegetService分别调用IServiceManager进行存取IBinder引用;
IServiceManager静态对象sServiceManager

1
sServiceManager = ServiceManagerNative.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));

其中BinderInternal.getContextObject()返回BinderProxyServiceManagerNative.asInterface返回ServiceManagerProxy。可以确定sServiceManager是一个Binder,ServiceManagerNative相当于“Stub”,ServiceManagerProxy相当于“Proxy”,但ServiceManagerNative的实现不在Java层,由JNI实现的,分析到此为止了。

知识点:

  • SystemServer进程是系统进程,也是Zygote创建的第一个进程。
  • AMS等系统服务运行在SystemServer进程中,由SystemServiceManager创建并添加到ServiceManager
  • ServiceManager负责系统服务等添加查找鉴权等,类似路由器概念,使用服务必须通过ServiceManager
  • 客户端和AMS通信可以理解为:1,客户端进程和SystemServer进程IPC拿到IServiceManager远端引用;2,IServiceManager通过缓存列表查找AMS远端引用;3,客户端进程使用AMS本地代理和SystemServer进程进行IPC。