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);
            }});
            ......
}
相关推荐
奋斗的阿狸_198623 分钟前
ch32v003j4m6+ws2812b方案2:规划引脚定义
linux
Mr-Apple38 分钟前
系统找不到指定的文件-CreateInstance/CreateVm/HCS/ERROR_FILE_NOT_FOUND
linux·windows·ubuntu·wsl
布裘1 小时前
【银河麒麟】服务器系统开机黑屏故障排查与修复
linux·运维·服务器·银河麒麟·无法启动
Zenova EdgeOS1 小时前
Linux iotop:工业边缘 I/O 高级分析实战
linux·运维·服务器
新兴AI民工1 小时前
【Linux内核三十九】进程管理模块:CFS负载均衡(四):find_busiest_group决策矩阵与calculate_imbalance
linux
LongRunning2 小时前
【linux】RK3568(五)云服务器-视频推流
linux
赵民勇2 小时前
resolvectl命令详解
linux·运维
新时代牛马2 小时前
Linux 日志管理:journald、rsyslog 与 logrotate
linux·运维·服务器
资深电气设计2 小时前
技术解析:ABB变频器ACH580/ACS180在CDU循环泵系统的应用技术框架
linux·运维·服务器
自律最差的编程狗2 小时前
Ubuntu下Docker部署Ollama 轻量模型
linux·ubuntu·docker