在分析无障碍服务接受事件响应时发现,ViewRootImpl 通过 Context.getSystemService(int)
方法获取了 AccessibilityManager,然后通过它向 AccessibilityManagerService 进行 Binder 调用,进而通知无障碍服务事件的,那么Context.getSystemService(String)
是如何获取 AccessibilityManager 的呢?这个获取流程是不是同 Binder 获取的呢?
以 frameworks/base/core/java/android/view/accessibility/AccessibilityManager.java
为例,介绍 XXXManager 的获取流程。通过 Context.getSystemService(String)
,获取到 AccessibilityManager 对象作为系统服务的对象。
系统行为可以通过 Context.getSystemService(ACCESSIBILITY_SERVICE)
获取 AccessibilityManager 对象进行调用,系统的服务统一在 frameworks/base/core/java/android/app/SystemServiceRegistry.java
中进行注册:
static {
registerService(Context.ACCESSIBILITY_SERVICE, AccessibilityManager.class,
new CachedServiceFetcher<AccessibilityManager>() {
@Override
public AccessibilityManager createService(ContextImpl ctx) {
return AccessibilityManager.getInstance(ctx);
}});
registerService(Context.ACTIVITY_SERVICE, ActivityManager.class,
new CachedServiceFetcher<ActivityManager>() {
@Override
public ActivityManager createService(ContextImpl ctx) {
return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
}});
// ...
}
Manager 的创建是在 Context.getSystemService(String)
方法中开始的,它的实际实现是在 ContextImpl 中:
@Override
public Object getSystemService(String name) {
// ...
return SystemServiceRegistry.getSystemService(this, name);
}
最终调用到了 SystemServiceRegistry 中:
// in SystemServiceRegistry
public static Object getSystemService(ContextImpl ctx, String name) {
if (name == null) {
return null;
}
final ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
if (fetcher == null) {
return null;
}
final Object ret = fetcher.getService(ctx);
if (sEnableServiceNotFoundWtf && ret == null) {
switch (name) {
case Context.CONTENT_CAPTURE_MANAGER_SERVICE:
case Context.APP_PREDICTION_SERVICE:
case Context.INCREMENTAL_SERVICE:
case Context.ETHERNET_SERVICE:
return null;
}
return null;
}
return ret;
}
在这个方法中,通过 ServiceFetcher 的 getService(ContextImpl)
方法返回了最终获取到的对象,而这个 ServiceFetcher 来自于 SYSTEM_SERVICE_FETCHERS
,它是一个 Map:
private static final Map<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS = new ArrayMap<String, ServiceFetcher<?>>();
往这个 Map 中存数据的调用在 registerService
中,也就是 SystemServiceRegistry
静态代码块中,注册的逻辑。
registerService(Context.ACTIVITY_SERVICE, ActivityManager.class,
new CachedServiceFetcher<ActivityManager>() {
@Override
public ActivityManager createService(ContextImpl ctx) {
return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
}});
这里在注册时,传入了一个 CachedServiceFetcher 对象,最终调用到的就是它的 getService :
public final T getService(ContextImpl ctx) {
final Object[] cache = ctx.mServiceCache;
final int[] gates = ctx.mServiceInitializationStateArray;
boolean interrupted = false;
T ret = null;
for (;;) {
boolean doInitialize = false;
synchronized (cache) {
T service = (T) cache[mCacheIndex];
if (service != null) {
ret = service;
break; // exit the for (;;)
}
if (gates[mCacheIndex] == ContextImpl.STATE_READY || gates[mCacheIndex] == ContextImpl.STATE_NOT_FOUND) {
gates[mCacheIndex] = ContextImpl.STATE_UNINITIALIZED;
}
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.
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 (;;)
}
// and go back to the top and retry. 其他线程将会等待第一个线程调用 notifyAll(), 返回 top 并且重试
synchronized (cache) {
while (gates[mCacheIndex] < ContextImpl.STATE_READY) {
try {
interrupted |= Thread.interrupted();
cache.wait();
} catch (InterruptedException e) {
Slog.w(TAG, "getService() interrupted");
interrupted = true;
}
}
}
}
if (interrupted) {
Thread.currentThread().interrupt();
}
return ret;
}
这里执行了三个步骤:
-
从缓存中直接获取对象,尝试获取若显示未初始化,则进入初始化服务阶段 -
调用 createService(contextImpl)
创建服务 -
其他线程等待当前线程创建完成更新缓存
从这几个步骤可以发现,创建逻辑调用到了 createService(contextImpl)
方法,而这个方法,在 registerService 时,不同的服务有不同的实现,例如 AccessbilityManager 和 ActivityManager 是直接 new 了一个对象。有的则是通过 Binder 机制,获取了一个 IBinder,并将其封装为指定类型的服务:
// 直接 new
registerService(Context.ACTIVITY_SERVICE, ActivityManager.class,
new CachedServiceFetcher<ActivityManager>() {
@Override
public ActivityManager createService(ContextImpl ctx) {
return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
}});
// binder 获取后封装
registerService(Context.ACCOUNT_SERVICE, AccountManager.class,
new CachedServiceFetcher<AccountManager>() {
@Override
public AccountManager createService(ContextImpl ctx) throws ServiceNotFoundException {
IBinder b = ServiceManager.getServiceOrThrow(Context.ACCOUNT_SERVICE);
IAccountManager service = IAccountManager.Stub.asInterface(b);
return new AccountManager(ctx, service);
}});
// ...
至此, XXXManager 的获取流程就结束了。从代码结构上看,这是一个标准的策略模式。
原文始发于微信公众号(八千里路山与海):Context.getSystemService 获取 Manager 的底层实现
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/60192.html