所有和Activity相关的Window初始化都在Activity的attach方法里面,该方法会在Activity被创建的时候执行
Window:窗体抽象类,主要实现对象是PhoneWindow,主要成员:
// 创建窗口默认会创建对应的窗体布局参数
private final WindowManager.LayoutParams mWindowAttributes =
new WindowManager.LayoutParams();
PhoneWindow:Window的主要实现类
ViewManager:View管理者接口,主要提供添加view,更新view,删除view的接口
public void addView(View view, ViewGroup.LayoutParams params);
public void updateViewLayout(View view, ViewGroup.LayoutParams params);
public void removeView(View view);
windowManager 接口,继承了ViewManager.
WindowManager.LayoutParams:Window窗体添加布局参数,父类是ViewGroup.LayoutParams
public LayoutParams() {
super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
type = TYPE_APPLICATION;//添加窗体的类型
format = PixelFormat.OPAQUE;
}
主要参数:type:窗体类型,主要有三种。应用窗体、子窗体、系统窗体;
Window 层级
应用 Window 1~99
子 Window 1000~1999
系统 Window 2000~2999
flags:这个主要是设置窗体的模式,我们看下一些常见的,具体参考
https://blog.csdn.net/zyjzyj2/article/details/53819964
public IBinder token = null;//Identifier for this window. 该窗口的身份验证口令,对应非系统窗口如果token不对,WMS会拒绝添加window,这也就是为什么dialog必须依附在Activity上
windowManagerImpl WindowManager的实现者,主要方法:
public WindowManagerImpl createLocalWindowManager(Window parentWindow) {
return new WindowManagerImpl(mContext, parentWindow);//创建一个本地WindowManager,就是它自己
}
private WindowManagerImpl(Context context, Window parentWindow) {
mContext = context;
mParentWindow = parentWindow;//这个parentWindow非常重要,后面讲token的时候
}
所以在activity里面通过getWindowManager获取到的对象就是它。
WindowManager的创建:
我们都知道在调用activity的attach函数的时候,会创建phonewindow顺便会设置WindowManager
if (wm == null) {
wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
}
mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);
如果wm为null,那么通过getSystemService获取到一个WindowManagerImpl,如果不为空,那么调用它的createLocalWindowManager方法创建一个
我们先看不为null的情况
public WindowManagerImpl createLocalWindowManager(Window parentWindow) {
return new WindowManagerImpl(mContext, parentWindow);
}
该方法就是想刚刚创建的phoneWindow传入进来,新建一个WindowManagerImpl。
如果wm为null,那么会调用mContext的getSystemService方法获取一个。这里需要注意下这个mContext的类型
对应PhoneWindow来说,这个mContext是一个acticity,我们看下acivity里面的getSystemService方法
@Override
public Object getSystemService(@ServiceName @NonNull String name) {
if (getBaseContext() == null) {
throw new IllegalStateException(
"System services not available to Activities before onCreate()");
}
if (WINDOW_SERVICE.equals(name)) {
return mWindowManager;
} else if (SEARCH_SERVICE.equals(name)) {
ensureSearchManager();
return mSearchManager;
}
return super.getSystemService(name);
}
如果是一个windowservice,那么会直接返回创建好的windowManager,那么对于首次初始化,这里肯定是null。那么是怎么保证获取到一个不为null呢
我们看最开始的地方
mWindow.setWindowManager(
(WindowManager)context.getSystemService(Context.WINDOW_SERVICE),