美文网首页
Android系统服务

Android系统服务

作者: 左大人 | 来源:发表于2018-09-22 15:28 被阅读0次

    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<LayoutInflater>() {
                    @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 <T> void registerService(String serviceName, Class<T> serviceClass,
            ServiceFetcher<T> serviceFetcher) {
        SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
        SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
    }
    

    实际上就是把Name,Class,ServiceFetcher保存在两个静态HashMap中,在获取系统服务时先通过Name找到ServiceFetcher,再通过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<?>>();
    

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

    /**
     * Base interface for classes that fetch services.
     * These objects must only be created during static initialization.
     */
    static abstract interface ServiceFetcher<T> {
        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系统服务

          本文链接:https://www.haomeiwen.com/subject/hihxoftx.html