系统服务 SystemServiceRegistry

在开发过程中,常常会用到系统服务,有时候也会添加一些系统服务;
这里看一下Android P相关源码;

在APP层获取系统服务的接口是getSystemService;
它被定义在frameworks/base/core/java/android/content/Context.java

public abstract @Nullable Object getSystemService(@ServiceName @NonNull String name);
这里的@ServiceName是一个注解,限定了输入,如果对注解内容不是很了解可以看下本人下面的文章:

Java注解,小试牛刀

这个直接定义在Context.java中,之所以要特地提一下这个注解,是因为在它限定了输入内容之后,我们新加的服务如果想通过getSystemService被拿到,就得同步把名字加到这个注解里;

当然Context.java内方法的具体的实现都在frameworks/base/core/java/android/app/ContextImpl.java里面;

@Override
public Object getSystemService(String name) {
    return SystemServiceRegistry.getSystemService(this, name);
}
这里引出了一个关键的类SystemServiceRegistry;
先看一下名词解释;

/**
 * Manages all of the system services that can be returned by {@link Context#getSystemService}.
 * Used by {@link ContextImpl}.
 * @hide
 */
public final class SystemServiceRegistry
再整体看一眼SystemServiceRegistry这个类;
位置:frameworks/base/core/java/android/app/SystemServiceRegistry.java
代码不多才1000多行;

它的构造方法是私有的,不允许被实例化;

// Not instantiable.
private SystemServiceRegistry() { }
主要成员变量;

// Service registry information.
// This information is never changed once static initialization has completed.
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<?>>();
private static int sServiceCacheSize;
类里面会静态地把很多系统服务加到cache里面,这里分别看3种不同类型的例子,下面会有更多介绍;

static {
    registerService(Context.ACCESSIBILITY_SERVICE, AccessibilityManager.class,
            new CachedServiceFetcher<AccessibilityManager>() {
                @Override
                public AccessibilityManager createService(ContextImpl ctx) {
                    return AccessibilityManager.getInstance(ctx);
            }});
            
    //...
    registerService(Context.JOB_SCHEDULER_SERVICE, JobScheduler.class,
            new StaticServiceFetcher<JobScheduler>() {
                @Override
                public JobScheduler createService() throws ServiceNotFoundException {
                    IBinder b = ServiceManager.getServiceOrThrow(Context.JOB_SCHEDULER_SERVICE);
                    return new JobSchedulerImpl(IJobScheduler.Stub.asInterface(b));
            }});
    //...
    registerService(Context.CONNECTIVITY_SERVICE, ConnectivityManager.class,
            new StaticApplicationContextServiceFetcher<ConnectivityManager>() {
                @Override
                public ConnectivityManager createService(Context context) throws ServiceNotFoundException {
                    IBinder b = ServiceManager.getServiceOrThrow(Context.CONNECTIVITY_SERVICE);
                    IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
                    return new ConnectivityManager(context, service);
                }});
    //...
}
主要的API:

/**
 * 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;
}
 
/**
 * Gets the name of the system-level service that is represented by the specified class.
 */
public static String getSystemServiceName(Class<?> serviceClass) {
    return SYSTEM_SERVICE_NAMES.get(serviceClass);
}
 
/**
 * 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);
}
主要注册、获取服务、获取服务名称这三个;
这里涉及到一个称为ServiceFetcher的东西,它是注册服务和获取服务的关键;

其实它是一个接口,用来获取真正的服务;

/**
 * Base interface for classes that fetch services.
 * These objects must only be created during static initialization.
 */
public static abstract interface ServiceFetcher<T> {
    T getService(ContextImpl ctx);
}
一共有3个抽象类实现了此接口:
CachedServiceFetcher、StaticServiceFetcher、StaticApplicationContextServiceFetcher
它们的工作方式是:如果服务已经存在就直接返回,如果不存在就调用createService抽象方法创建一个;

/**
 * Override this class when the system service constructor needs a
 * ContextImpl and should be cached and retained by that context.
 */
public static abstract class CachedServiceFetcher<T> implements ServiceFetcher<T> {
    private final int mCacheIndex;
 
    public CachedServiceFetcher() {
        // Note this class must be instantiated only by the static initializer of the
        // outer class (SystemServiceRegistry), which already does the synchronization,
        // so bare access to sServiceCacheSize is okay here.
        mCacheIndex = sServiceCacheSize++;
    }
 
    @Override
    @SuppressWarnings("unchecked")
    public final T getService(ContextImpl ctx) {
        //...
    }
 
    public abstract T createService(ContextImpl ctx) throws ServiceNotFoundException;
}
 
/**
 * Override this class when the system service does not need a ContextImpl
 * and should be cached and retained process-wide.
 */
static abstract class StaticServiceFetcher<T> implements ServiceFetcher<T> {
    private T mCachedInstance;
 
    @Override
    public final T getService(ContextImpl ctx) {
        synchronized (StaticServiceFetcher.this) {
            //...
            return mCachedInstance;
        }
    }
 
    public abstract T createService() throws ServiceNotFoundException;
}
 
/**
 * Like StaticServiceFetcher, creates only one instance of the service per application, but when
 * creating the service for the first time, passes it the application context of the creating
 * application.
 *
 * TODO: Delete this once its only user (ConnectivityManager) is known to work well in the
 * case where multiple application components each have their own ConnectivityManager object.
 */
static abstract class StaticApplicationContextServiceFetcher<T> implements ServiceFetcher<T>{
    private T mCachedInstance;
 
    @Override
    public final T getService(ContextImpl ctx) {
        //...
        return mCachedInstance;
    }
 
    public abstract T createService(Context applicationContext) throws ServiceNotFoundException;
}
小结:
SystemServiceRegistry这个东西维护了所有的服务,具体服务在哪儿还得从对应的createService里面找;

转自  系统服务 SystemServiceRegistry-CSDN博客