Android 系统服务管理 ServiceManager

之前在装饰器模式中提到了 Context 只是一个抽象类,具体的实现内容都是由 ContextImpl 来完成的。

而在 Context 中定义了很多的方法,比如 getString()、startActivity()、sendBroadcast() 等等,在 Activity 中我们经常会用到这些方法。而这些方法的实现当然也是在 ContextImpl 中了。不过,由于 Activity 的继承关系,得在源码中 ContextWrapper 中看到具体的实现调用。其中,还有一段这样的注释:

  1. /**
  2. * Set the base context for this ContextWrapper. All calls will then be
  3. * delegated to the base context. Throws
  4. * IllegalStateException if a base context has already been set.
  5. *
  6. * @param base The new base context for this wrapper.
  7. */
  8. protected void attachBaseContext(Context base) {
  9. if (mBase != null) {
  10. throw new IllegalStateException("Base context already set");
  11. }
  12. mBase = base;
  13. }

ServiceManager 管理服务

在应用程序编程时,经常使用到 getSystemService(String serviceName) 方法来获得一个系统服务,它的实现也是在 ContextImpl 中的,根据不同的参数返回不同的系统服务,这些系统服务都是由 ServiceManager 管理的。

在看 ContextImpl 具体实现代码之前,我们有必要了解一下 ServiceManager 这个概念。

ServiceManager 是一个独立的进程,它管理各种系统服务,如下图所示:

android_service_manager

ServiceManager 本身也是一个 Service ,Framework 提供了一个系统函数,可以获取该 Service 对应的 Binder 引用,那就是 BinderInternal.getContextObject() 。该静态函数返回 ServiceManager 后,就可以通过 ServiceManager 提供的方法获取系统其他 Service 的 Binder 引用。

这样的好处就是系统中仅暴露一个全局 Bindre 引用,那就是 ServiceManager ,而其他的系统服务则可以隐藏起来,从而有助于系统服务的拓展,以及调用系统服务的安全检查。其他系统服务在启动时,首先要把自己的 Binder 对象传递给 ServiceManager ,即所谓的注册(addService)。

说白了,ServiceManager 就相当于一个总机,需要其他系统服务时再转接获得其他服务,理解了这样的模型之后,再去看源码就会清楚很多了。

ServiceManager 相关源码

由于我编译的是 Android 6.0 的源码,和书上的基于 Android 4.0 及更早的代码已经有些不一样了,所以还是以 6.0 的源码为主。

首先从 ContextImpl 的 getSystemService 方法入手:

  1. @Override
  2. public Object getSystemService(String name) {
  3. return SystemServiceRegistry.getSystemService(this, name);
  4. }

可以看到 ContextImpl 返回的服务是通过 SystemServiceRegistry类的静态方法返回的。

而 SystemServiceRegistry 的 getSystemService 方法内容如下:

  1. /**
  2. * Gets a system service from a given context.
  3. */
  4. public static Object getSystemService(ContextImpl ctx, String name) {
  5. ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
  6. return fetcher != null ? fetcher.getService(ctx) : null;
  7. }

SYSTEM_SERVICE_FETCHERS 是一个 HashMap 类型,存储的内容为 HashMap<String,ServiceFetcher<?>> 。而在 getSystemService 方法中得到的就是一个 ServiceFetcher 类型。

而 ServiceFetcher 是一个接口类型,定义如下,它的 getService 方法就是返回所需的 Service 。

  1. /**
  2. * Base interface for classes that fetch services.
  3. * These objects must only be created during static initialization.
  4. */
  5. static abstract interface ServiceFetcher<T> {
  6. T getService(ContextImpl ctx);
  7. }

这样,就通过SYSTEM_SERVICE_FETCHERS这个容器得到ServiceFetcher,再调用它的getService方法得到了需要的 Service 。

但只是理清了如何得到 Service 还是不够,还要明白何时注册的 Service 。

在 SystemServiceRegistry 源码里有个 registerService 方法,它就是向SYSTEM_SERVICE_FETCHERS添加 ServiceFetcher

  1. /**
  2. * Statically registers a system service with the context.
  3. * This method must be called during static initialization only.
  4. */
  5. private static <T> void registerService(String serviceName, Class<T> serviceClass,
  6. ServiceFetcher<T> serviceFetcher) {
  7. SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
  8. SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
  9. }

代码的注释里同样提到了该方法只能在静态初始化时调用,而 SystemServiceRegistry 类有个 static 代码块, 按照 Java 代码的执行顺序,静态代码块肯定在静态方法 getSystemService 之前执行,这样就保证了SYSTEM_SERVICE_FETCHERS容器不至于为空了。

而最终通过 ServiceFetcher的 getService 方法返回的 Service 也是在 registerService 方法中传入的,查看其中某个 Service 代码如下:

posted @ 2017-09-14 17:40  天涯海角路  阅读(832)  评论(0)    收藏  举报