ams l = r.window.getAttributes();
//将decor赋给Activity的mDecor
a.mDecor = decor;
//type的数值是1
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;
if (a.mVisibleFromClient) {
a.mWindowAdded = true;
//将主View(decorView)添加到WindowManager中
wm.addView(decor, l);
}
}
}
我们在Context的分析中已经分析过,WindowManager实际上初始化的是WindowManagerImpl,通过它来进行各种操作,我们转到WindowManagerImpl.java分析addView
PhoneWindow.java
是这样获取DecorView的
public final View getDecorView() {
if (mDecor == null) {
installDecor();
}
return mDecor;
}
private void installDecor() {
if (mDecor == null) {
//创建DecorView,接着往下去看如何创建DecorView,DecorView是个什么?
mDecor = generateDecor();
mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
mDecor.setIsRootNamespace(true);
}
if (mContentParent == null) {
//这个mContentParent是干什么的?
mContentParent = generateLayout(mDecor);
}
}
private final class DecorView extends FrameLayout implements RootViewSurfaceTaker
{
public DecorView(Context context, int featureId) {
super(context);
mFeatureId = featureId;
}
/*
*DecorView中还实现了派发key event、key快捷方式等方法
*/
public boolean dispatchKeyEvent(KeyEvent event) {
……
}
public boolean dispatchKeyShortcutEvent(KeyEvent ev) {
……
}
}
由DecorView定义我们可以知道,DecorView是一个扩张的FrameLayout,它是所有当前的Activity中View的主View
WindowManagerImpl.java
public void addView(View view, ViewGroup.LayoutParams params, CompatibilityInfoHolder cih) {
addView(view, params, cih, false);
}
private void addView(View view, ViewGroup.LayoutParams params,
CompatibilityInfoHolder cih, boolean nest) {
//这说明将DecorView添加到WindowManager必须要满足下面这个条件,否则会报异常
if (!(params instanceof WindowManager.LayoutParams)) {
throw new IllegalArgumentException(
"Params must be WindowManager.LayoutParams");
}
final WindowManager.LayoutParams wparams
= (WindowManager.LayoutParams)params;
ViewRootImpl root;
View panelParentView = null;
synchronized (this) {
//主要是查看要添加的View是否已经在mViews中了,若有就返回对应的index
int index = findViewLocked(view, false);
if (index >= 0) {
if (!nest) {
throw new IllegalStateException("View " + view
+ " has already been added to the window manager.");
}
//为什么这样,因为若添加了view到mViews,那么mRoots也对应添加
root = mRoots[index];
root.mAddNesting++;
// Update layout parameters.
view.setLayoutParams(wparams);
root.setLayoutParams(wparams, true);
return;
}
root = new ViewRootImpl(view.getContext());
//第一次添加view到mView,mViews是还没有分配空间的
if (mViews == null) {
index = 1;
mViews = new View[1];
mRoots = new ViewRootImpl[1];
mParams = new WindowManager.LayoutParams[1];
} else {
// 里奇怪的是,为什么将mViews、mRoots中内容先保存然后再拷贝一遍呢?
index = mViews.length + 1;
Object[] old = mViews;
mViews = new View[index];
System.arraycopy(old, 0, mViews, 0, index-1);
old = mRoots;
mRoots = new ViewRootImpl[index];
System.arraycopy(old, 0, mRoots, 0, index-1);
old = mParams;
mParams = new WindowManager.LayoutParams[index];
System.arraycopy(old, 0, mParams, 0, index-1);
}