getSystemService
的定义
// frameworks/base/core/java/android/app/ContextImpl.java
@Override
public Object getSystemService(String name) {
if (vmIncorrectContextUseEnabled()) {
// Check incorrect Context usage.
if (WINDOW_SERVICE.equals(name) && !isUiContext()) {
final String errorMessage = "Tried to access visual service "
+ SystemServiceRegistry.getSystemServiceClassName(name)
+ " from a non-visual Context:" + getOuterContext();
final String message = "WindowManager should be accessed from Activity or other "
+ "visual Context. Use an Activity or a Context created with "
+ "Context#createWindowContext(int, Bundle), which are adjusted to "
+ "the configuration and visual bounds of an area on screen.";
final Exception exception = new IllegalAccessException(errorMessage);
StrictMode.onIncorrectContextUsed(message, exception);
Log.e(TAG, errorMessage + " " + message, exception);
}
}
return SystemServiceRegistry.getSystemService(this, name);
}
然后就是调用SystemServiceRegistry
中的getSystemService(ContextImpl ctx, String name)
//frameworks/base/core/java/android/app/SystemServiceRegistry.java
public static Object getSystemService(ContextImpl ctx, String name) {
if (name == null) {
return null;
}
// 关键点就是 ServiceFetcher 是什么
// 或许可以理解为 Service service在本地(当前进程)中的一个副本?
final ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
if (fetcher == null) {
if (sEnableServiceNotFoundWtf) {
Slog.wtf(TAG, "Unknown manager requested: " + name);
}
return null;
}
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:
case Context.CONTEXTHUB_SERVICE:
case Context.VIRTUALIZATION_SERVICE:
case Context.VIRTUAL_DEVICE_SERVICE:
return null;
}
Slog.wtf(TAG, "Manager wrapper not available: " + name);
return null;
}
return ret;
}
我们来看一下ServiceFetcher的定义。在CachedServiceFetcher
的构造函数中会对sServiceCacheSize
进行自增运算。sServiceCacheSize
是SystemServiceRegistry
中的类变量,代表了system service 的数量。
//frameworks/base/core/java/android/app/SystemServiceRegistry.java
/**
* Base interface for classes that fetch services.
* These objects must only be created during static initialization.
*/
static abstract interface ServiceFetcher<T> {
T getService(ContextImpl ctx);
}
/**
* Override this class when the system service constructor needs a
* ContextImpl and should be cached and retained by that context.
*/
static abstract class CachedServiceFetcher<T> implements ServiceFetcher<T> {
private final int mCacheIndex;
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++;//mCacheIndex 决定了这个service存储在mServiceCache中的位置
}
@Override
@SuppressWarnings("unchecked")
public final T getService(ContextImpl ctx) {
//这个函数的实现暂时略过,后面再说
}
public abstract T createService(ContextImpl ctx) throws ServiceNotFoundException;
}
在SystemServiceRegistry
中,以static
代码块的形式注册了system service。后面会讨论,system service注册的过程。这里只需要知道每注册一个system service,都会new
一个CachedServiceFetcher
,从而使sServiceCacheSize
+1。
static {
//CHECKSTYLE:OFF IndentationCheck
registerService(Context.ACCESSIBILITY_SERVICE, AccessibilityManager.class,
new CachedServiceFetcher<AccessibilityManager>() {
@Override
public AccessibilityManager createService(ContextImpl ctx) {
return AccessibilityManager.getInstance(ctx);
}});
...
sInitializing = true;
try {
// Note: the following functions need to be @SystemApis, once they become mainline
// modules.
...
WifiFrameworkInitializer.registerServiceWrappers();
...
} finally {
// If any of the above code throws, we're in a pretty bad shape and the process
// will likely crash, but we'll reset it just in case there's an exception handler...
sInitializing = false;
}
}
sServiceCacheSize
的作用就是让ContextImpl
可以获取一个system service数量的数组mServiceCache
,它里面储存了诸如xxxManager
的对象
frameworks/base/core/java/android/app/SystemServiceRegistry.java
/**
* Creates an array which is used to cache per-Context service instances.
* @hide
*/
public static Object[] createServiceCache() {
return new Object[sServiceCacheSize];
}
frameworks/base/core/java/android/app/ContextImpl.java
final Object[] mServiceCache = SystemServiceRegistry.createServiceCache();
接下来看一下CachedServiceFetcher.getService(ContextImpl ctx)
的实现
frameworks/base/core/java/android/app/SystemServiceRegistry.java
public final T getService(ContextImpl ctx) {
final Object[] cache = ctx.mServiceCache;//mServiceCache 是ContextImpl 用以存储system service的数组
//mServiceInitializationStateArray存储service的初始化状态,
//STATE_UNINITIALIZED, STATE_INITIALIZING,STATE_READY
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.
T service = (T) cache[mCacheIndex];//cache[mCacheIndex]就是应该用来存储当前service的位置
if (service != null) {
ret = service;
break; // exit the for (;;)
}
//如果找不到这个service,那么进行初始化
// 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.
if (gates[mCacheIndex] == ContextImpl.STATE_UNINITIALIZED) {
doInitialize = true;
gates[mCacheIndex] = ContextImpl.STATE_INITIALIZING;
}
}
if (doInitialize) {
// Only the first thread gets here.
// 这里正式进行service初始化
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.
service = createService(ctx);
//createService 在 CachedServiceFetcher中没有实现,他依赖于注册服务时传入的参数
//后面会根据WiFiManager进行分析
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.
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;
}
下面来看WifiManager
是怎么注册的,它的注册是在WifiFrameworkInitializer.registerServiceWrappers()
中完成的
packages/modules/Wifi/framework/java/android/net/wifi/WifiFrameworkInitializer.java
public static void registerServiceWrappers() {
SystemServiceRegistry.registerContextAwareService(
Context.WIFI_SERVICE,
WifiManager.class,
(context, serviceBinder) -> {
if (!context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_WIFI)) {
return null;
}
IWifiManager service = IWifiManager.Stub.asInterface(serviceBinder);
return new WifiManager(context, service, getInstanceLooper());
}
);
...
}
frameworks/base/core/java/android/app/SystemServiceRegistry.java
public static <TServiceClass> void registerContextAwareService(
@NonNull String serviceName, @NonNull Class<TServiceClass> serviceWrapperClass,
@NonNull ContextAwareServiceProducerWithBinder<TServiceClass> serviceProducer) {
ensureInitializing("registerContextAwareService");
Preconditions.checkStringNotEmpty(serviceName);
Objects.requireNonNull(serviceWrapperClass);
Objects.requireNonNull(serviceProducer);
registerService(serviceName, serviceWrapperClass,
new CachedServiceFetcher<TServiceClass>() {
@Override
public TServiceClass createService(ContextImpl ctx)
throws ServiceNotFoundException {
return serviceProducer.createService(
ctx.getOuterContext(),
//获取IBinder对象
ServiceManager.getServiceOrThrow(serviceName));
}});
}