Android系统服务


image.png

序言

在Android系统中,我们经常会通过Context获取系统级别的服务,如WindowsManagerService、ActivityManagerService、LayoutInflater。
那么这些系统服务是什么时候初始化的呢,又是如何获取的呢?

跟踪源码

我们就以LayoutInflater为例,进行分析。开发过程中,获取LayoutInflater的方式如下:

LayoutInflater.from(this@TradeModifyActivity).inflate(R.layout.topbar_trade_page, null)

跟踪LayoutInflater.from方法

/**
 * Obtains the LayoutInflater from the given context.
 */
public static LayoutInflater from(Context context) {
    LayoutInflater LayoutInflater =
            (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    if (LayoutInflater == null) {
        throw new AssertionError("LayoutInflater not found.");
    }
    return LayoutInflater;
}

实际是调用context.getSystemService()来获取LayoutInflater,就以Activity的context为例来分析。大家都知道,Activity的Context实现类是ContextImpl类。

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

转而调用SystemServiceRegistry.getSystemService()方法

/**
 * Gets a system service from a given context.
 */
public static Object getSystemService(ContextImpl ctx, String name) {
    ServiceFetcher fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
    return fetcher != null ? fetcher.getService(ctx) : null;
}

到这里,主体脉络已经捋清楚了,现在来看一下SystemServiceRegistry这个类。该类包含一段静态代码块:

static {
    //内容过长,就不完全展示出来,主要是注册各种系统服务
    ......
    
    //注册LayoutInflator
    registerService(Context.LAYOUT_INFLATER_SERVICE, LayoutInflater.class,
                    new CachedServiceFetcher() {
                @Override
                public LayoutInflater createService(ContextImpl ctx) {
                    return new PhoneLayoutInflater(ctx.getOuterContext());
                }});
                
    ......
}

看一下registerService方法

/**
 * Statically registers a system service with the context.
 * This method must be called during static initialization only.
 */
private static  void registerService(String serviceName, Class serviceClass,
        ServiceFetcher serviceFetcher) {
    SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
    SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
}

实际上就是把Name,Class,ServiceFetcher保存在两个静态HashMap中,在获取系统服务时先通过Name找到ServiceFetcher,再通过ServiceFetcher获取真正的服务对象。

private static final HashMap, String> SYSTEM_SERVICE_NAMES = new HashMap, String>();
private static final HashMap> SYSTEM_SERVICE_FETCHERS = new HashMap>();

接下来看一下ServiceFetcher,该类定义如下:

/**
 * Base interface for classes that fetch services.
 * These objects must only be created during static initialization.
 */
static abstract interface ServiceFetcher {
    T getService(ContextImpl ctx);
}

该类只有一个getService方法,该类有三个实现类:CachedServiceFetcher,StaticServiceFetcher、StaticApplicationContextServiceFetcher。它们都有一个抽象方法createService,区别在于,createService接收的参数:

  • CachedServiceFetcher需要ContextImpl
public abstract T createService(ContextImpl ctx) throws ServiceNotFoundException;
  • StaticServiceFetcher不需要ContextImpl
public abstract T createService() throws ServiceNotFoundException;
  • StaticApplicationContextServiceFetcher需要Application的Context
public abstract T createService(Context applicationContext) throws ServiceNotFoundException;

这些系统服务都只会创建一个对象(单例模式),第一次获取服务时,通过ServiceFetcher的createService创建服务对象,然后将该对象存在静态HashMap中,下次直接从缓存中获取,避免重复创建对象。

总结

以后使用系统服务的时候大家就很清楚这些服务的注册和获取方式了,他们采用容器单例实现方式,通过HashMap来管理一组单例对象,很好的设计思想,值得大家学习。

你可能感兴趣的:(Android系统服务)