目录
前言
记录一下getSystemService()获取的源码流程,加深一下印象。
正文
这里以获取AudioManager为例
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
getSystemService()定义在Context.java中
public static final String AUDIO_SERVICE = "audio";
Context.java
frameworks\base\core\java\android\content\Context.java
public abstract @Nullable Object getSystemService(@ServiceName @NonNull String name);
抽象方法。
Context的实现类是ContextImpl,具体看ContextImpl.java
ContextImpl.java
\frameworks\base\core\java\android\app\ContextImpl.java
@Override public Object getSystemService(String name) { if (vmIncorrectContextUseEnabled()) { //略 } //重点关注后面的 return SystemServiceRegistry.getSystemService(this, name); }
SystemServiceRegistry.java
\frameworks\base\core\java\android\app\SystemServiceRegistry.java
我们一开始传入的name是Context.AUDIO_SERVICE,也就是audio。
public static Object getSystemService(ContextImpl ctx, String name) { //不为null if (name == null) { return null; } //SYSTEM_SERVICE_FETCHERS是map,存储了服务相关信息 final ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name); if (fetcher == null) { if (sEnableServiceNotFoundWtf) { Slog.wtf(TAG, "Unknown manager requested: " + name); } return null; } //获取服务,这里需要重点关注fetcher 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; } return null; } return ret; }
上面重点关注的是SYSTEM_SERVICE_FETCHERS和ServiceFetcher。
SYSTEM_SERVICE_FETCHERS
private static final Map<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS = new ArrayMap<String, ServiceFetcher<?>>();
具体看哪里添加的
registerService
//私有的静态变量,类内部使用 private static <T> void registerService(@NonNull String serviceName, @NonNull Class<T> serviceClass, @NonNull ServiceFetcher<T> serviceFetcher) { SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName); //这里添加的 SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher); SYSTEM_SERVICE_CLASS_NAMES.put(serviceName, serviceClass.getSimpleName()); }
这里有多个map存储服务相关信息,我们这里值关注SYSTEM_SERVICE_FETCHERS。
第一个是服务名,第二个是serviceFetcher。
在SystemServiceRegistry中有一个静态代码块,这里注册了
Context.ACTIVITY_SERVICE Context.AUDIO_SERVICE Context.ACCOUNT_SERVICE Context.ACCESSIBILITY_SERVICE Context.HDMI_CONTROL_SERVICE 等
这里只关注AUDIO_SERVICE的注册。
static{ //略 registerService(Context.AUDIO_SERVICE, AudioManager.class, new CachedServiceFetcher<AudioManager>() { @Override public AudioManager createService(ContextImpl ctx) { return new AudioManager(ctx); }}); //略 }
第三个是匿名创建CachedServiceFetcher
CachedServiceFetcher
static abstract class CachedServiceFetcher<T> implements ServiceFetcher<T> { private final int mCacheIndex; CachedServiceFetcher() { mCacheIndex = sServiceCacheSize++; } @Override @SuppressWarnings("unchecked") 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) { T service = null; @ServiceInitializationState int newState = ContextImpl.STATE_NOT_FOUND; try { 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; } synchronized (cache) { while (gates[mCacheIndex] < ContextImpl.STATE_READY) { try { interrupted |= Thread.interrupted(); cache.wait(); } catch (InterruptedException e) { interrupted = true; } } } } if (interrupted) { Thread.currentThread().interrupt(); } return ret; } public abstract T createService(ContextImpl ctx) throws ServiceNotFoundException; }
上面代码很多,但最重要的是需要重写的createService()。
因此回到上面第三个参数创建匿名CachedServiceFetcher对象代码处。
new CachedServiceFetcher<AudioManager>() { @Override public AudioManager createService(ContextImpl ctx) { return new AudioManager(ctx); }}
这里是直接返回了新创建的AudioManager对象。
至此,上面
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
就类似等价于
AudioManager audioManager = new AudioManager(ctx);
参考文章
历史上的今天
暂无评论...
随机推荐
狄兰·托马斯:不要温和地走进那个良夜
不要温和地走进那个良夜,老年应当在日暮时燃烧咆哮;怒斥,怒斥光明的消逝。虽然智慧的人临终时懂得黑暗有理,因为他们的话没有迸发出闪电,他们也并不温和地走进那个良夜。善良的人,当最后一浪过去,高呼他们脆弱的善行可能曾会多么光辉地在绿色的海湾里舞蹈,怒斥,怒斥光明的消逝。狂暴的人抓住并歌唱过...
Android Studio工程中.idea没有*.iml文件
前言我使用其他同事电脑时,Android Studio(Android Studio Dolphin | 2021.3.1 Patch 1)的版本新建的工程中.idea目录没有对应module和*.iml。百度或谷歌后解决了。记录一下,方便自己查阅。正文解决这个问题很简单,就是Androi...
Android修改原生电话铃声
前言简单记录一下,修改Android原生默认的铃声。推荐看参考文章,这里只是个人随笔记录。正文隐藏内容!付费阅读后才能查看!¥1 ¥3多个隐藏块只需支付一次付费阅读参考文章《Android 设置铃声》《Android 设置来电铃声、通知铃声、闹钟铃声中的坑》
Android startActivity去掉自带的动画效果
Android中startActivity系统自带动画效果,如果需要取消动效,可以考虑如下两种方式。使用overridePendingTransition在启动Activity后添加此代码Intent intent = new Intent(mContext, MainActivity.cl...
朱自清:洋槐
那个时刻我便为它幽幽地滋生出一种感动,自己的心似乎也变得干净而澄明。雨后清新的湿气萦绕书桌徘徊不去,我想这书桌会不会是用洋槐木做成的呢?否则为何它负载着沉重的思维却依然结实有力。洋槐给我一春一夏的绿色,到秋天,艳阳在树顶涂出一抹金黄,不几日,窗前已被装点得金碧辉煌。秋风乍起,金色的槐树叶如雨纷纷飘...
自定义垂直Seekbar简介之progressDrawable显示优化2
前言之前《自定义垂直Seekbar简介》文章中说过,通过drawBitmap直接画图片时,如果边角存在椭圆就没法正常显示。这里就优化一下,上一个版本的问题,具体效果图如图。正文直接展示效果图(未显示Thumb)可以看出,这里两边都有圆角的。原理主要代码跟《自定义垂直Seekba...