美文网首页Android开发Android知识
Android6.0之App获取系统service的过程

Android6.0之App获取系统service的过程

作者: 小爨 | 来源:发表于2016-08-23 11:39 被阅读0次

    Android系统中提供了很多Service,如剪切板服务,AMS服务等.很有必要一个app是如何获得这些service的.

    app中如何获取Android系统中提供的service

    app是通过context来获取的.

    例如获取AMS:

    ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
    

    getSystemService()方法是Activity类中定义.

    @Override
       public Object getSystemService(@ServiceName @NonNull String name) {
           if (getBaseContext() == null) {
               throw new IllegalStateException(
                       "System services not available to Activities before onCreate()");
           }
    
           if (WINDOW_SERVICE.equals(name)) {
               return mWindowManager;
           } else if (SEARCH_SERVICE.equals(name)) {
               ensureSearchManager();
               return mSearchManager;
           }
           return super.getSystemService(name);
       }
    

    而Activity继承自ContextThemeWrapper:

    AMS-30.png

    ContextThemeWrapper中定义了getSystemService()方法:

    
    @Override public Object getSystemService(String name) {
            if (LAYOUT_INFLATER_SERVICE.equals(name)) {
                if (mInflater == null) {
                    mInflater = LayoutInflater.from(getBaseContext()).cloneInContext(this);
                }
                return mInflater;
            }
            return getBaseContext().getSystemService(name);
        }
    

    getBaseContext()方法来自ContextWrapper类:

    
    public Context getBaseContext() {
           return mBase;
       }
    

    getSystemService()方法也就是来自ContextImpl:

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

    SystemServiceRegistry类getSystemService()

    public static Object getSystemService(ContextImpl ctx, String name) {
            ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
            return fetcher != null ? fetcher.getService(ctx) : null;
        }
    

    SYSTEM_SERVICE_FETCHERS也定义在SystemServiceRegistry类中,是一个hashmap,key是name,value是实现了ServiceFetcher接口的一个对象:

    final class SystemServiceRegistry {
        private final static String TAG = "SystemServiceRegistry";
        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;
    
    ....................
      }
    

    ServiceFetcher 是一接口:

    static abstract interface ServiceFetcher<T> {
           T getService(ContextImpl ctx);
       }
    

    那么现在的问题就是SYSTEM_SERVICE_FETCHERS这个hashmap是什么时候初始化的.

    在SystemServiceRegistry类中只有registerService()这个方法操作了SYSTEM_SERVICE_FETCHERS:

    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);
       }
    

    该方法是一个私有方法,那么看谁调了它:

    final class SystemServiceRegistry {
      .........
        // Not instantiable.
        private SystemServiceRegistry() { }
    
        static {
            registerService(Context.ACCESSIBILITY_SERVICE, AccessibilityManager.class,
                    new CachedServiceFetcher<AccessibilityManager>() {
                @Override
                public AccessibilityManager createService(ContextImpl ctx) {
                    return AccessibilityManager.getInstance(ctx);
                }});
        ..........
        registerService(Context.ACTIVITY_SERVICE, ActivityManager.class,
                  new CachedServiceFetcher<ActivityManager>() {
              @Override
              public ActivityManager createService(ContextImpl ctx) {
                  return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
              }});
        ...............
      }
    

    SystemServiceRegistry静态代码块中调用了registerService()方法.

    也就是说当SystemServiceRegistry类初始化的时候,就会在其静态代码块中执行registerService()方法,填充SYSTEM_SERVICE_FETCHERS这个hashmap.

    前面执行SystemServiceRegistry.getSystemService()方法时,如果是该类还没初始化,那么就会先进行类初始化.当类初始化完成之后,SYSTEM_SERVICE_FETCHERS这个hashmap中已经被初始化好了,可以通过name直接寻找其对应的value.这个value是模块类CachedServiceFetcher子类的对象.这个对象调用其createService()方法返回name对应的service.

    要彻底搞明白这个过程的话,还需要分析SystemServiceRegistry类的registerService()方法的第三个参数:

    以AMS为例:

    registerService(Context.ACTIVITY_SERVICE, ActivityManager.class,
                    new CachedServiceFetcher<ActivityManager>() {
                @Override
                public ActivityManager createService(ContextImpl ctx) {
                    return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
                }});
    

    registerService方法:

    第一个参数 service的名字:

        public static final String ACTIVITY_SERVICE = "activity";
    

    第二个参数:

    AMS代理类:ActivityManager

    第三个参数:是一个实现了serviceFetcher接口的模块类CachedServiceFetcher的子类对象:

    先看类CachedServiceFetcher:

    static abstract class CachedServiceFetcher<T> implements ServiceFetcher<T> {
        private final int mCacheIndex;
    
        public CachedServiceFetcher() {
            mCacheIndex = sServiceCacheSize++;
        }
    
        @Override
        @SuppressWarnings("unchecked")
        public final T getService(ContextImpl ctx) {
            final Object[] cache = ctx.mServiceCache;
            synchronized (cache) {
                // Fetch or create the service.
                Object service = cache[mCacheIndex];
                if (service == null) {
                    service = createService(ctx);
                    cache[mCacheIndex] = service;
                }
                return (T)service;
            }
        }
    
        public abstract T createService(ContextImpl ctx);
    }
    

    对于AMS来说,其T为ActivityManager.

    CachedServiceFetcher这个模块类很简单,就是实现了ServiceFetcher接口中getService()方法.

    同时定义了一个抽象方法:T createService().那么其子类要负责实现这个创建Service的方法.

    最终通过registerService()方法,第一个参数作为key将第三个参数存入了SYSTEM_SERVICE_FETCHERS这个hashmap中.

    这样就彻底清晰了.当App中通过下面所示代码获取AMS时:

    ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
    

    实际上是传递了两个参数一个是Activity的context,另一个AMS的name.首先以name为key在SystemServiceRegistry.SYSTEM_SERVICE_FETCHERS找到AMS的CachedServiceFetcher<ActivityManager>子类对象.

    然后调用这个对象的getService()方法:

    public final T getService(ContextImpl ctx) {
        final Object[] cache = ctx.mServiceCache;
        synchronized (cache) {
            // Fetch or create the service.
            Object service = cache[mCacheIndex];
            if (service == null) {
                service = createService(ctx);
                cache[mCacheIndex] = service;
            }
            return (T)service;
        }
    }
    

    传入的ctx就是这个app的一个context.首次获取时从缓存中是查询不到的,所以会调用createService()方法先创建:

    public ActivityManager createService(ContextImpl ctx) {
        return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
    }}
    

    然后返回给调用者.

    缓存机制

    当调用这createService()方法创建对象之后,为了下次能快速获取,所以将其缓存起来了.

    将其存储到了App的ContextImpl类的mServiceCache:

    // The system service cache for the system services that are cached per-ContextImpl.
    final Object[] mServiceCache = SystemServiceRegistry.createServiceCache();
    

    下次在获取的时候,直接从context的缓存中拿.其中索引mCacheIndex在创建CachedServiceFetcher子类对象的时候的初始化.和其在SystemServiceRegistry静态代码块中注册的顺序一致.

    通过以上分析可以如果想要直到App中通过getSystemService()方法获得到底是什么对象,看SystemServiceRegistry类中的静态代码块便知道了.

    相关文章

      网友评论

        本文标题:Android6.0之App获取系统service的过程

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