赞
踩
- 在开发过程中,常常会用到系统服务,有时候也会添加一些系统服务;
- 这里看一下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里面找;

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。