当我们需要添加一个悬浮窗口时,都会先通过getSystemService去获取WindowManager,再通过WindowManager的addView、updateViewLayout、removeView方法来实现,那么getSystemService是怎么实现的呢,它具体返回的是哪个类?
1.我们通常用如下方式来获取WindowManager:
Context.getSystemService(Context.WINDOW_SERVICE)
2.Android studio查看源码,跳转到ContextWrapper,该类继承Context,Context是个抽象类。
Activity、Service、Application都是集成自ContextWrapper,Activity集成自ContextThemeWrapper
frameworks/base/core/java/android/content/ContextWrapper.java
@Override
public Object getSystemService(String name) {
return mBase.getSystemService(name);
}
ContextWrapper的getSystemService调用了mBase的getSystemService,mBase是Context
Context mBase;
mBase具体指向的是ContextImpl对象,通过attachBaseContext方法赋值
protected void attachBaseContext(Context base) {
if (mBase != null) {
throw new IllegalStateException("Base context already set");
}
mBase = base;
}
赋值的流程大概如下
frameworks/base/core/java/android/app/ActivityThread.java
->handleLaunchActivity
->performLaunchActivity->attach
frameworks/base/core/java/android/app/Actiity.java
->attach->attachBaseContext
具体可参考:https://blog.csdn.net/future234/article/details/80902393
3.到这里我知道了,Context的getSystemService具体调的是ContextImpl的getSystemService方法,因此直接去看ContextImpl。
如下,ContextImpl调用了SystemServiceRegistry的getSystemService方法
frameworks/base/core/java/android/app/ContextImpl.java
@Override
public Object getSystemService(String name) {
return SystemServiceRegistry.getSystemService(this, name);
}
4.SystemServiceRegistry的getSystemService方法是个静态方法,源码如下
frameworks/base/core/java/android/app/SystemServiceRegistry.java
public static String getSystemServiceName(Class<?> serviceClass) {
return SYSTEM_SERVICE_NAMES.get(serviceClass);
}
这里的SYSTEM_SERVICE_NAMES是个HashMap
private static final HashMap<Class<?>, String> SYSTEM_SERVICE_NAMES =
new HashMap<Class<?>, String>();
SYSTEM_SERVICE_NAMES通过registerService方法put数据
private static <T> void registerService(String serviceName, Class<T> serviceClass,
ServiceFetcher<T> serviceFetcher) {
SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
}
registerService是private方法,所以注册服务也是在SystemServiceRegistry里,WindowManager注册如下
registerService(Context.WINDOW_SERVICE, WindowManager.class,
new CachedServiceFetcher<WindowManager>() {
@Override
public WindowManager createService(ContextImpl ctx) {
return new WindowManagerImpl(ctx);
}});
所以,Context.getSystemService(Context.WINDOW_SERVICE)具体返回的类是WindowManagerImpl
所有的系统服务在启动阶段都是被SystemServer进程启动,其中在startOtherServices方法里会调用(WindowManager)context.getSystemService(Context.WINDOW_SERVICE)
系统在启动时,将众多系统服务以及它们的名字注册到一个哈希表中,当应用端调用getSystemService时,根据指定的name参数,返回对应的服务实例。app即可通过此实例获得对应的服务