frameworks 之 触摸事件窗口查找
- [1. SystemServiceRegistry 获取服务](#1. SystemServiceRegistry 获取服务)
- [2. ServiceFetcher 获取流程](#2. ServiceFetcher 获取流程)
- [3. ServiceFetcher 注册](#3. ServiceFetcher 注册)
讲解 SystemServiceRegistry 获取系统服务管理类流程
涉及到的类如下
- frameworks/base/core/java/android/app/SystemServiceRegistry.java
1. SystemServiceRegistry 获取服务
通过 context 获取的 getSystemService 服务最终都会调用 SystemServiceRegistry 的getSystemService方法。该方法流程
- 从 SYSTEM_SERVICE_FETCHERS hashMap 里面通过名称获取对应的 fetcher对象
- 判断获取回来的 fetcher 对象是否为空,为空则根据是否打印日志返回 null
- 如果不为空,在调用 getService 方法获取对应的对象
- 判断是否为空,为空且打印日志则打印,并返回对应的对象
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 方法。该方法主要步骤
- 从对应的context 获取缓存的数组 和 缓存的状态
- 根据初始化的 mCacheIndex获取对应的缓存数组如果有则返回
- 获取不到将对应的状态设置为没初始化,并将判断是否未初始化,没有的话置为初始化中,并将变量值为 doInitialize
- 通过调用对应的 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);
}});
......
}