Window相关类
基于Android U
Window、WindowManager和WMS的关系
Window是一个抽象类,具体的实现类为PhoneWindow,它对View进行管理。
WindowManager是一个接口类,继承自接口ViewManager,它是用来管理Window的,它的实现类为WindowManagerImpl。如果我们想要对Window(View)进行添加、更新和删除操作就可以使用WindowManager,WindowManager会将具体的工作交由WMS来处理,WindowManager和WMS通过Binder来进行跨进程通信,WMS作为系统服务有很多API是不会暴露给WindowManager的。

Window包含了View并对View进行管理,Window用虚线来表示是因为Window是一个抽象概念,用来描述一个窗口,并不是真实存在的,Window的实体其实也是View。WindowManager用来管理Window,而WindowManager所提供的功能最终会由WMS进行处理。
WindowManager相关方法
WindowManager是一个接口类,继承自接口ViewManager,ViewManager中定义了三个方法,分别用来添加、更新和删除View。
1 |
|
WindowManager也继承了这些方法,而这些方法传入的参数都是View类型,说明Window是以View的形式存在的。WindowManager在继承ViewManager的同时,又加入很多功能,包括Window的类型和层级相关的常量、内部类以及一些方法,其中有两个方法是根据Window的特性加入的:
1 |
|
getDefaultDisplay()方法能够得知这个WindowManager实例将Window添加到哪个屏幕上了,换句话说,就是得到WindowManager所管理的屏幕(Display)。
removeViewImmediate()方法则规定在这个方法返回前要立即执行View.onDetachedFromWindow(),来完成传入的View相关的销毁工作。
PhoneWindow相关方法
PhoneWindow是在Activity创建的attach()方法中创建的。
1 |
|
注释1处创建了PhoneWindow,注释2处调用PhoneWindow#setWindowManager()方法,这个方法在PhoneWindow的父类Window中实现。
1 |
|
如果传入的WindowManager为null,就会在注释1处调用Context#getSystemService()方法,并传入服务的名称Context。WINDOW_SERVICE(值为window),具体在ContextImpl中实现。
1
2
3
4
5frameworks/base/core/java/android/app/ContextImpl.java
public Object getSystemService(String name) {
...
return SystemServiceRegistry.getSystemService(this, name);
}调用SystemServiceRegistry#getSystemService()方法。
1
2
3
4
5
6
7
8
9frameworks/base/core/java/android/app/SystemServiceRegistry.java
public static Object getSystemService(ContextImpl ctx, String name) {
...
final ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
...
final Object ret = fetcher.getService(ctx);
...
return ret;
}SYSTEM_SERVICE_FETCHERS是一个ArrayMap,其Key为系统服务名,Value为ServiceFetcher对象。
SYSTEM_SERVICE_FETCHERS是在什么时候被赋值的?
1
2
3
4
5
6
7frameworks/base/core/java/android/app/SystemServiceRegistry.java
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());
}registerService()方法是什么时候被调用的?
1
2
3
4
5
6
7
8
9
10
11frameworks/base/core/java/android/app/SystemServiceRegistry.java
static {
...
registerService(Context.WINDOW_SERVICE, WindowManager.class,
new CachedServiceFetcher<WindowManager>() {
@Override
public WindowManager createService(ContextImpl ctx) {
return new WindowManagerImpl(ctx); // 1
}});
...
}在SystemServiceRegistry的静态代码块中会调用多个registerService()方法,registerService()方法内部会将传入的服务的名称存入到SYSTEM_SERVICE_FETCHERS中。从注释1处可以看出,传入的Context.WINDOW_SERVICE对应的就是WindowManagerImpl实例。
mContext.getSystemService()得到WindowManagerImpl实例后转为WindowManager类型,在注释2处调用了WindowManagerImpl#createLocalWindowManager()方法。
1
2
3
4frameworks/base/core/java/android/view/WindowManagerImpl.java
public WindowManagerImpl createLocalWindowManager(Window parentWindow) {
return new WindowManagerImpl(mContext, parentWindow, mWindowContextToken);
}createLocalWindowManager()方法同样也是创建WindowManagerImpl,不同的是这次创建WindowManagerImpl时将创建它的Window作为参数传了进来,这样WindowManagerImpl就持有了Window的引用,可以对Window进行操作,比如在Window中添加View,会调用WindowManagerImpl的addView()方法,如下所示:
1
2
3
4
5
6
7frameworks/base/core/java/android/view/WindowManagerImpl.java
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
android.util.SeempLog.record_vg_layout(383,params);
applyTokens(params);
mGlobal.addView(view, params, mContext.getDisplayNoVerify(), mParentWindow,
mContext.getUserId()); // 1
}注释1处调用了WindowManagerGlobal的addView()方法,其中参数mParentWindow就是上面提到的Window,可以看出WindowManagerImpl虽然是WindowManage的实现类,但是没有实现什么功能,而是将功能实现委托给了WindowManagerGlobal,这里用到的是桥接模式。
我们来查看WindowManagerImpl中是如何定义WindowManagerGlobal的。
1 |
|
注释1处可以看出WindowManagerGlobal是一个单例,说明在一个进程中只有一个WindowManagerGlobal实例。
注释2处结合注释3处说明这个WindowManagerImpl实例会作为哪个Window的子Window,这也就说明在一个进程中WindowManagerImpl可能会有多个实例。
通过如上的源码分析,WindowManager的关联类如下图所示:
从图中可以看出,PhoneWindow继承自Window,Window通过setWindowManager()方法与WindowManager发生关联。WindowManager继承自接口ViewManager,WindowManagerImpl是WindowManager接口的实现类,但是具体的功能都会委托给WindowManagerGlobal来实现。