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);
            }});
            ......
}
相关推荐
NYKJ.Co2 分钟前
开疆智能Ethernet/IP转Profinet网关连接纳博特控制器配置案例
linux·服务器·tcp/ip
俺不理解1 小时前
Android Compose 悬浮窗
android·生命周期·compose·悬浮窗
鳄鱼皮坡1 小时前
【linux系统】基础开发工具(yum、Vim)
linux·c++·ubuntu
qq_377572771 小时前
vim save
linux·vim
运维小文1 小时前
vim优化
linux·编辑器·vim
苏柘_level61 小时前
解决 Android 应用日志中 JDWP 报错问题
android
Devil枫1 小时前
安卓开发--使用android studio发布APP
android·ide·android studio
VVVVWeiYee2 小时前
新华三预赛考前突击
linux·服务器·网络·数据库·信息与通信
nn_302 小时前
UOS AI 2.0 发布,开启原生 AIOS 时代!
linux·运维·服务器·人工智能·科技
草明2 小时前
使用 ADB (Android Debug Bridge) 工具来截取 Android 设备的屏幕截图
android·adb