ServiceManager是用来管理系统服务的。
1.系统启动时向ServiceManager中添加服务
系统启动时会启动SystemServer进程,SystemServer进程会开启引导服务,核心服务以及其他服务,这些服务开启成功之后会被添加到ServiceManager中,如:
InputManagerService inputManager = new InputManagerService(context);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
这些系统服务同时也是IBinder,可以理解成ServiceManager中有一个HashMap,以键值对的方式保存了这些系统服务的IBinder句柄;
2.应用启动时向SystemServiceRegistry中注册服务在应用端的代理
应用进程在启动时会创建一个Context,也就是ContextImpl,ContextImpl会把该应用所有支持的系统服务在应用端的代理添加到SystemServiceRegistry中:
ContextImpl.java
final Object[] mServiceCache = SystemServiceRegistry.createServiceCache();
SystemServiceRegistry.java
private static final HashMap<Class<?>, String> SYSTEM_SERVICE_NAMES =
new HashMap<Class<?>, String>();
private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS =
new HashMap<String, ServiceFetcher<?>>();
static {
......
registerService(Context.ALARM_SERVICE, AlarmManager.class,
new CachedServiceFetcher<AlarmManager>() {
@Override
public AlarmManager createService(ContextImpl ctx) throws ServiceNotFoundException {
//以Context.ALARM_SERVICE为key,在ServiceManager中找到对应的IBinder
IBinder b = ServiceManager.getServiceOrThrow(Context.ALARM_SERVICE);
//将IBinder转化成IAlarmManager接口
IAlarmManager service = IAlarmManager.Stub.asInterface(b);
return new AlarmManager(service, ctx);
}});
......
}
private static <T> void registerService(String serviceName, Class<T> serviceClass,
ServiceFetcher<T> serviceFetcher) {
SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
}
static abstract class StaticServiceFetcher<T> implements ServiceFetcher<T> {
private T mCachedInstance;
@Override
public final T getService(ContextImpl ctx) {
synchronized (StaticServiceFetcher.this) {
if (mCachedInstance == null) {
try {
mCachedInstance = createService();
} catch (ServiceNotFoundException e) {
onServiceNotFound(e);
}
}
return mCachedInstance;
}
}
public abstract T createService() throws ServiceNotFoundException;
}
SystemServiceRegistry中有一个HashMap--SYSTEM_SERVICE_FETCHERS,以键值对的方式保存了系统服务在客户端的代理;
3.app端通过Binder机制调用系统服务功能
①app端通过getSystemService来得到系统服务在客户端的代理:
InputManager= (InputManager) context.getSystemService(Context.INPUT_SERVICE);
ContextImpl.java
public Object getSystemService(String name) {
return SystemServiceRegistry.getSystemService(this, name);
}
SystemServiceRegistry.java
public static Object getSystemService(ContextImpl ctx, String name) {
ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
return fetcher != null ? fetcher.getService(ctx) : null;
}
得到InputManager后,就可以调用其api,InputManager会通过Binder机制的跨进程通信将应用端的操作传递给系统服务InputManagerService