frameworks 之 SystemServiceRegistry

frameworks 之 触摸事件窗口查找

  • [1. SystemServiceRegistry 获取服务](#1. SystemServiceRegistry 获取服务)
  • [2. ServiceFetcher 获取流程](#2. ServiceFetcher 获取流程)
  • [3. ServiceFetcher 注册](#3. ServiceFetcher 注册)

讲解 SystemServiceRegistry 获取系统服务管理类流程
涉及到的类如下

  1. frameworks/base/core/java/android/app/SystemServiceRegistry.java

1. SystemServiceRegistry 获取服务

通过 context 获取的 getSystemService 服务最终都会调用 SystemServiceRegistrygetSystemService方法。该方法流程

  1. SYSTEM_SERVICE_FETCHERS hashMap 里面通过名称获取对应的 fetcher对象
  2. 判断获取回来的 fetcher 对象是否为空,为空则根据是否打印日志返回 null
  3. 如果不为空,在调用 getService 方法获取对应的对象
  4. 判断是否为空,为空且打印日志则打印,并返回对应的对象
java 复制代码
	public static Object getSystemService(ContextImpl ctx, String name) {
        if (name == null) {
            return null;
        }
        // 从缓存中获取是否为空
        final ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
        if (fetcher == null) {
            if (sEnableServiceNotFoundWtf) {
                Slog.wtf(TAG, "Unknown manager requested: " + name);
            }
            return null;
        }
        // 调用 getService 里面会判断是否有对象 没有将调用对应的 createService 方法
        final Object ret = fetcher.getService(ctx);
        if (sEnableServiceNotFoundWtf && ret == null) {
            // Some services do return null in certain situations, so don't do WTF for them.
            switch (name) {
                case Context.CONTENT_CAPTURE_MANAGER_SERVICE:
                case Context.APP_PREDICTION_SERVICE:
                case Context.INCREMENTAL_SERVICE:
                case Context.ETHERNET_SERVICE:
                    return null;
            }
            Slog.wtf(TAG, "Manager wrapper not available: " + name);
            return null;
        }
        return ret;
    }

2. ServiceFetcher 获取流程

ServiceFetcher 是一个接口类对应实现的类为 CachedServiceFetcher。CachedServiceFetcher 初始化构造方法会通过静态变量 sServiceCacheSize 进行自增,并保存到 mCacheIndex 队列下

java 复制代码
		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++;
        }

查看对应的 getService 方法。该方法主要步骤

  1. 从对应的context 获取缓存的数组 和 缓存的状态
  2. 根据初始化的 mCacheIndex获取对应的缓存数组如果有则返回
  3. 获取不到将对应的状态设置为没初始化,并将判断是否未初始化,没有的话置为初始化中,并将变量值为 doInitialize
  4. 通过调用对应的 createService 方法获取,果找到就将状态置为STATE_READY,否则抛异常接下来循环获取直到状态为 STATE_READY 或者 STATE_NOT_FOUND
java 复制代码
		public final T getService(ContextImpl ctx) {
            // 当前 context 缓存的数组
            final Object[] cache = ctx.mServiceCache;
            // 当前 context对应服务的情况
            final int[] gates = ctx.mServiceInitializationStateArray;
            boolean interrupted = false;

            T ret = null;

            for (;;) {
                boolean doInitialize = false;
                synchronized (cache) {
                    // Return it if we already have a cached instance.
                    // 获取当前 context的下标是否已经缓存,缓存了就直接返回
                    T service = (T) cache[mCacheIndex];
                    if (service != null) {
                        ret = service;
                        break; // exit the for (;;)
                    }

                    // If we get here, there's no cached instance.

                    // Grr... if gate is STATE_READY, then this means we initialized the service
                    // once but someone cleared it.
                    // We start over from STATE_UNINITIALIZED.
                    // Similarly, if the previous attempt returned null, we'll retry again.
                    // 将对应的状态设置为没初始化
                    if (gates[mCacheIndex] == ContextImpl.STATE_READY
                            || gates[mCacheIndex] == ContextImpl.STATE_NOT_FOUND) {
                        gates[mCacheIndex] = ContextImpl.STATE_UNINITIALIZED;
                    }

                    // It's possible for multiple threads to get here at the same time, so
                    // use the "gate" to make sure only the first thread will call createService().

                    // At this point, the gate must be either UNINITIALIZED or INITIALIZING.
                    // 判断是否未初始化,没有的话置为初始化中,并将变量值为 doInitialize
                    if (gates[mCacheIndex] == ContextImpl.STATE_UNINITIALIZED) {
                        doInitialize = true;
                        gates[mCacheIndex] = ContextImpl.STATE_INITIALIZING;
                    }
                }

                if (doInitialize) {
                    // Only the first thread gets here.

                    T service = null;
                    @ServiceInitializationState int newState = ContextImpl.STATE_NOT_FOUND;
                    try {
                        // This thread is the first one to get here. Instantiate the service
                        // *without* the cache lock held.
                        // 调用对应的 createService, 如果找到就将状态置为STATE_READY,否则抛异常
                        service = createService(ctx);
                        newState = ContextImpl.STATE_READY;

                    } catch (ServiceNotFoundException e) {
                        onServiceNotFound(e);

                    } finally {
                        synchronized (cache) {
                            // 将状态放到最新的数组里
                            cache[mCacheIndex] = service;
                            gates[mCacheIndex] = newState;
                            cache.notifyAll();
                        }
                    }
                    ret = service;
                    break; // exit the for (;;)
                }
                // The other threads will wait for the first thread to call notifyAll(),
                // and go back to the top and retry.
                synchronized (cache) {
                    // Repeat until the state becomes STATE_READY or STATE_NOT_FOUND.
                    // We can't respond to interrupts here; just like we can't in the "doInitialize"
                    // path, so we remember the interrupt state here and re-interrupt later.
                    // 一直循环,直到状态为 STATE_READY 或者 STATE_NOT_FOUND
                    while (gates[mCacheIndex] < ContextImpl.STATE_READY) {
                        try {
                            // Clear the interrupt state.
                            interrupted |= Thread.interrupted();
                            cache.wait();
                        } catch (InterruptedException e) {
                            // This shouldn't normally happen, but if someone interrupts the
                            // thread, it will.
                            Slog.w(TAG, "getService() interrupted");
                            interrupted = true;
                        }
                    }
                }
            }
            if (interrupted) {
                Thread.currentThread().interrupt();
            }
            return ret;
        }

3. ServiceFetcher 注册

所有的注册对应代码在 SystemServiceRegistry 的 静态代码块中,也就是说当SystemServiceRegistry类初始化的时候 ,就会在其静态代码块执行注册。并实现其对应的 createService 方法。

java 复制代码
static {
        //CHECKSTYLE:OFF IndentationCheck
        registerService(Context.ACCESSIBILITY_SERVICE, AccessibilityManager.class,
                new CachedServiceFetcher<AccessibilityManager>() {
            @Override
            public AccessibilityManager createService(ContextImpl ctx) {
                return AccessibilityManager.getInstance(ctx);
            }});
            ......
}
相关推荐
lllsure3 小时前
Linux 实用指令
linux·物联网
openinstall全渠道统计3 小时前
免填邀请码工具:赋能六大核心场景,重构App增长新模型
android·ios·harmonyos
努力的小T3 小时前
使用 Docker 部署 Apache Spark 集群教程
linux·运维·服务器·docker·容器·spark·云计算
Nerd Nirvana3 小时前
OpenSSL crt & key (生成一套用于TLS双向认证的证书密钥)
linux·ssl·shell·认证·加密·tls·oepnssl
双鱼大猫3 小时前
一句话说透Android里面的ServiceManager的注册服务
android
双鱼大猫3 小时前
一句话说透Android里面的查找服务
android
双鱼大猫3 小时前
一句话说透Android里面的SystemServer进程的作用
android
双鱼大猫4 小时前
一句话说透Android里面的View的绘制流程和实现原理
android
letisgo54 小时前
记录一次部署PC端网址全过程
linux·阿里云·服务器运维
双鱼大猫4 小时前
一句话说透Android里面的Window的内部机制
android