写在前面
开发过程中,我们经常需要一些系统服务,比如 LayoutInflater、ActivityManager 等等,每次获取的时候我们都直接调用 Activity,Service 的 getSystemService(String name) 这个方法,然而这个方法是什么工作的?每次获取的对象是不是一个?我们都不太清楚,今天,我们就来揭开 getSystemService 方法的面纱,剖析他的工作过程。
概要
系统启动
系统启动时会调用 SystemServer.main(),其中会调用 SystemThread.run() 方法,该方法中调用 SystemServiceManager 的 startService 方法使用反射实例化 AMS、PMS… 等系统对象
IServiceManager 通过 Binder 机制向外提供 AMS、PMS… 等系统服务
应用进程
在 Native 层通过通过 Binder 获取 IServiceManager 在应用进程的代理
ServiceManager 类代理 ServiceManagerProxy(是 IServiceManager 在客户端的代理类)
通过 ServiceManager 获取 AMS、PMS 等系统服务在客户端的代理
IServiceManager 是 Binder 进程间通信机制的守护进程,其目的非常简单,就是管理 Android 系统里的 Binder 对象
通过下面的解析,我们会发现一个毁三观的事情,那就是 LayoutInflater 、ActivityManager 并不是单例的,我靠,大神们快来撕逼,反正我今天搞完是大吃一惊。
注意:以下说的 service 是指系统服务的对象名,并不是我们的四大组件中的 Service ,千万不要乱,这里不涉及四大组件中的 Service
开始
平时我们获取系统服务都是直接通过 Context 对象的 getService(String name) 方法来获取,这个方法是在 ContextImpl 中的实现的
@Override
public Object getSystemService(String name) {
return SystemServiceRegistry.getSystemService(this, name);
}
调用了 SystemServiceRegistry.getSystemService(this, name) 方法,我们接着往下看
public static Object getSystemService(ContextImpl ctx, String name) {
ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
return fetcher != null ? fetcher.getService(ctx) : null;
}
getSystemService 方法中会在 SYSTEM_SERVICE_FETCHERS 中根据 name 来取一个 ServiceFetcher 对象,有必要先看看这两个对象是什么了
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 abstract interface ServiceFetcher<T> {
T getService(ContextImpl ctx);
}
SYSTEM_SERVICE_NAMES 是 SystemServiceRegistry 类中的一个常量,类型为一个 HashMap,key 为想要获取的系统服务的对应 Class,value 为