1、Window、WindowManager和WMS
- Window是一个抽象类,具体的实现类为PhoneWindow,它对View进行管理
- WindowManager是一个接口类,继承自接口ViewManager,用来管理Window的,它的实现类为WindowManagerImpl
- WindowManger会将具体的工作交给WMS来处理,WindowManager和WMS通过Binder来进行跨进程通信
总的来说就是 WindowManger 将工作交给WMS来处理,并且对Window进行管理,也就是对View进行管理
2、WindowManager 的关联类
1、WindowManager是一个接口类,继承自接口ViewManager,ViewManager中定义了三个方法分别用来添加、更新和删除View
public interface ViewManager{
public void addView(View view, ViewGroup.LayoutParams params)
public void updateViewLayout(View view, ViewGroup.LayoutParams params)
public void removeView(View view)
}
WindowManager 也继承了这些方法,而这些方法传入的参数都是View类型,说明Window是以View的形式存在的,在继承这些方法的同时,又加入了很多功能,其中有两个方法是根据Window的特性加入的
/**
* 能够得知这个Window Manager实例将Window添加到哪个屏幕上了,
* 也就是说得到WindowManager所管理的屏幕(Display)
**/
public Display getDefaultDisplay()
/**
* 在这个方法返回前要立即执行View.onDetachedFromWindow()来
* 完成出入的View相关的销毁工作
**/
public void removeViewImmediate(View view)
Window是一个抽象类,具体实现类为PhoneWindow,PhoneWindow是在Activity的attach方法中创建的
2、context的getSystemService方法得到的是WindowManagerImpl实例
WindowManagerImpl.createLocalWindowManager() 方法同样创建WindowManagerImpl,不过这次创建时会将创建它的Window作为参数传了进来,这样WindowManagerImpl就持有了Window的引用,可以对Window进行操作
3、PhoneWindow 继承自 Window,Window通过setWindowManager方法与WindowManager发生关联。WindowManager继承自接口 ViewManager,WindowManagerImpl是WindowManager 接口的实现类,但是具体的功能都会委托给 WindowManagerGlobal 来实现
3、Window 的属性
Window的属性有很多种,与应用开发最密切的有3种:Type(Window的类型)、Flag(Window的标志)和SelfInputMode(软键盘相关模式)
Window的类型和显示次序
Window分为三大类型,分别是Application Window(应用程序窗口)、SubWindow(子窗口)、SystemWindow(系统窗口),每个大类型中又包含了很多类型,都定义在Window Manager的静态内部类LayoutParams中
- 应用程序窗口
Activity就是一个典型的应用程序窗口,包含的类型如下:
final int FIRST_APPLICATION_WINDOW = 1;//窗口类型的初始值,其他的窗口值要大于这个值
final int LAST_APPLICATION_WINDOW = 99;//应用程序窗口类型的结束值,也就是说应用程序窗口的Type值范围为1~99
- 子窗口
子窗口需要附着在其他窗口才可以,PopupWindow就属于子窗口。子窗口的Type值范围为1000~1999
- 系统窗口
Toast、输入法窗口、系统音量条窗口、系统错误窗口都属于系统窗口,其Type值的范围为2000~2999
- 窗口显示次序
当一个进程向WMS申请一个窗口时,WMS会为窗口确定显示次序。为了方便窗口显示次序的管理,手机屏幕可以虚拟地用x、y、z轴来表示,z轴垂直于屏幕,从屏幕内指向屏幕外,这样确定窗口显示次序也就是确定窗口在z轴上的次序,这个次序称为Z-oder,type值是Z-oder排序的依据,Type值越大则Z-oder排序越靠前,就越靠近用户
Window的标志
Window的标志也就是Flag,用于控制Window的显示,同样被定义在WindowManager的内部类LayoutParams中
设置Window的Flag有3中方法,第一种是通过Window的addFlags方法:
Window mWindow = getWindow()
mWindow.addFlags(WindowManger.LayoutParams.FLAS_FULLSCREEN)
第二种通过Window的setFlag方法,其实Window的addFlags方法内部会调用setFlags方法
Window mWindow = getWindow()
mWindow.setFlags(WindManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
第三种是给LayoutParams设置Flag,并通过WindowManager的addView方法进行添加
WindowManager.LayourParams mWLP= new WindowManager.LayoutParams();
mWLP.flags = WindowManager.LayoutParams.FLAG_FULLSCREEN;
WindowManager mWM = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
TextView tv = new TextView(this);
mWM.addView(tv, mWLP);
软键盘相关模式
WindowManager的静态内部类LayoutParams中定义了软键盘相关模式,这里给出常用的几个:(SoftInputMode)
SOFT_INPUT_STATE_UNSPECIFIED: 没有指定状态,系统会选择一个合适的状态或依赖于主题的设置
SOFT_INPUT_STATE_UNCHANGED: 不会改变软键盘状态,从给出的SoftInputMode可以发现,与AndroidManifest中Activity的属性 android:windowSoftInputMode是对应的,因此可在此设置,也可用代码设置
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
Window的操作
Window的添加、更新和删除操作系统称为Window的操作,对于Window的操作最终都是交由WMS来进行处理的。窗口的操作分为两大部分,一部分是WindowManager处理部分,另一部分是WMS处理部分