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);
            }});
            ......
}
相关推荐
子春一26 分钟前
Flutter 与原生平台深度集成:打通 iOS 与 Android 的最后一公里
android·flutter·ios
小邓   ༽1 小时前
全场景Android测试:API、工具与案例,从TestCase到Mock类应用指南
android·android 测试·android 组件测试·mock 类·测试 api 应用·组件测试核心
霍夫曼2 小时前
UTC时间与本地时间转换问题
java·linux·服务器·前端·javascript
月熊3 小时前
在root无法通过登录界面进去时,通过原本的普通用户qiujian如何把它修改为自己指定的用户名
linux·运维·服务器
大江东去浪淘尽千古风流人物3 小时前
【DSP】向量化操作的误差来源分析及其经典解决方案
linux·运维·人工智能·算法·vr·dsp开发·mr
赖small强4 小时前
【Linux驱动开发】NOR Flash 技术原理与 Linux 系统应用全解析
linux·驱动开发·nor flash·芯片内执行
享哥。4 小时前
android MVP模式代码示例
android
IT运维爱好者5 小时前
【Linux】LVM理论介绍、实战操作
linux·磁盘扩容·lvm
LEEE@FPGA5 小时前
ZYNQ MPSOC linux hello world
linux·运维·服务器