Activity中层级分为
Activity->PhoneWindow->decorView->[appbar 和 contentView]
其中phoneWindow是window的唯一实现,phoneWindow在activity的attach方法中初始化
Activity的attach是AMS执行到ActivityThread中的handleMessage中执行launchActivity方法调用,执行完attach后会执行Activity的onCreate方法
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
//....
if (activity != null) {
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor);
//....
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
}
用户调用setContentView时 按照继承的关系分为两种:
1.继承Activity或者FragmentActivity
直接调用window的setContentView方法
public void setContentView(@LayoutRes int layoutResID) {
getWindow().setContentView(layoutResID);
initWindowDecorActionBar();
}
在PhoneWindow的伪代码为为
@Override
public void setContentView(int layoutResID) {
if (mContentParent == null) {
installDecor();
}
//加载app的布局文件
mLayoutInflater.inflate(layoutResID, mContentParent);
}
第一步是如果mContentParent为空 也就是说deCorView没初始化,执行installDecor
private void installDecor() {
if (mDecor == null) {
mDecor = generateDecor();
}
if (mContentParent == null) {
mContentParent = generateLayout(mDecor);
if (decorContentParent != null) {
mDecorContentParent = decorContentParent;
} else {
//...
}
}
其中generateDecor是new一个DecorView
protected DecorView generateDecor() {
return new DecorView(getContext(), -1);
}
//类声明
private final class DecorView extends FrameLayout implements RootViewSurfaceTaker
generateLayout方法主要是对于decorView的属性进行初始化,例如设置标题,图标设置页面样式,
我们代码设置全屏为什么要在setCotentView之前也是这个原因
if (a.getBoolean(R.styleable.Window_windowNoTitle, false)) {
requestFeature(FEATURE_NO_TITLE);
} else if (a.getBoolean(R.styleable.Window_windowActionBar, false)) {
// Don't allow an action bar if there is no title.
requestFeature(FEATURE_ACTION_BAR);
}
2.继承AppCompatActivity
是通过一个工厂方法根据编译的系统版本获得对象mDelegate对象
@Override
public void setContentView(@LayoutRes int layoutResID) {
getDelegate().setContentView(layoutResID);
}
setContentView最终会调用AppCompatDelegateImplV7的setContentView方法
@Override
public void setContentView(int resId) {
ensureSubDecor();
ViewGroup contentParent = (ViewGroup) mSubDecor.findViewById(android.R.id.content);
contentParent.removeAllViews();
LayoutInflater.from(mContext).inflate(resId, contentParent);
mOriginalWindowCallback.onContentChanged();
}
ensureSubDecor方法最终会调用 根据设置加载"subDecor"的布局,和activity的方式不一样没用到decorView
private ViewGroup createSubDecor() {
TypedArray a = mContext.obtainStyledAttributes(R.styleable.Theme);
//设置窗口样式
if (a.getBoolean(R.styleable.Theme_windowNoTitle, false)) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
} else if (a.getBoolean(R.styleable.Theme_windowActionBar, false)) {
// Don't allow an action bar if there is no title.
requestWindowFeature(FEATURE_SUPPORT_ACTION_BAR);
}
final LayoutInflater inflater = LayoutInflater.from(mContext);
ViewGroup subDecor = null;
if (!mWindowNoTitle) {
if (mIsFloating) {
// If we're floating, inflate the dialog title decor
subDecor = (ViewGroup) inflater.inflate(
R.layout.abc_dialog_title_material, null);
// Floating windows can never have an action bar, reset the flags
mHasActionBar = mOverlayActionBar = false;
} else if (mHasActionBar) {
// Now inflate the view using the themed context and set it as the content view
subDecor = (ViewGroup) LayoutInflater.from(themedContext)
.inflate(R.layout.abc_screen_toolbar, null);
mDecorContentParent = (DecorContentParent) subDecor
.findViewById(R.id.decor_content_parent);
}
} else {
if (mOverlayActionMode) {
subDecor = (ViewGroup) inflater.inflate(
R.layout.abc_screen_simple_overlay_action_mode, null);
} else {
subDecor = (ViewGroup) inflater.inflate(R.layout.abc_screen_simple, null);
}
// Now set the Window's content view with the decor
mWindow.setContentView(subDecor);
return subDecor;
}
WindowaManager在activity的attach中初始化,它自身是个接口类, 继承接口ViewManager,这个三个方法是WindowManager提供给就是activity控制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);
}
WindowaManager 实现类是WindowManagerImpl,里面获取WindowManagerGlobal,是具体的方法实现
public final class WindowManagerImpl implements WindowManager {
private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
@Override
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
applyDefaultToken(params);
mGlobal.addView(view, params, mDisplay, mParentWindow);
}
@Override
public void updateViewLayout(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
applyDefaultToken(params);
mGlobal.updateViewLayout(view, params);
}
@Override
public void removeView(View view) {
mGlobal.removeView(view, false);
}
}
WindowManager存放三个数组
//存放创建的View
private final ArrayList mViews = new ArrayList();
private final ArrayList mRoots = new ArrayList();
//存放view的属性
private final ArrayList mParams =
new ArrayList();