基于 android 4.4 src:
Activity 的 setContentView():
public void setContentView(View view, ViewGroup.LayoutParams params) {
getWindow().setContentView(view, params);
initActionBar();
}
首先做的是将Avticity绑定的phoneWindow(通过getWindow())将inflate出来的view set为phoneWindow的view.
然后才是初始化系统的actionBar.
PhoneWindow.java
@Override
public void setContentView(View view, ViewGroup.LayoutParams params) {
if (mContentParent == null) {
installDecor(); 如果PhoneWindow里面的DecorView的mContentParent还没有被install上,那么就install
} else {
mContentParent.removeAllViews(); 如果之前已经有mContentParent了,那么将mContentParent里的所有view清空
}
mContentParent.addView(view, params); 将要set 的 view加入到decorView里的mContentParent中
final Callback cb = getCallback();
if (cb != null && !isDestroyed()) {
cb.onContentChanged();
}
}
DecorView本质就是一个FrameLayout
private final class DecorView extends FrameLayout implements RootViewSurfaceTaker
install DecorView到phoneWindow的过程
private void installDecor() {
if (mDecor == null) {
mDecor = generateDecor();
很简单,return new DecorView(getContext(), -1);
/** The feature ID of the panel, or -1 if this is the application's DecorView */
mFeatureId 是 -1
mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
mDecor.setIsRootNamespace(true);
if (!mInvalidatePanelMenuPosted && mInvalidatePanelMenuFeatures != 0) {
mDecor.postOnAnimation(mInvalidatePanelMenuRunnable);
}
}
if (mContentParent == null) {
mContentParent = generateLayout(mDecor);
generateLayout()会设置一堆的flag到window,
然后会从 layout.screen_simple_overlay_action_mode / layout.screen_simple中选择一个进行inflate,
然后加入到decorView中,
而后,调用ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
其中ID_ANDROID_CONTENT = com.android.internal.R.id.content
而window的findViewById()其实是getDecorView().findViewById(id),因此
contentParent代表其实就是刚才加入到decorView中的layout中的一个view,及decorView包含了一个view,
该view又包含contentParent, 而contentParent就是mContentParent, acticity setContainerView()所
set的view就是被加入到了这个mContentParent中。
// Set up decor part of UI to ignore fitsSystemWindows if appropriate.
mDecor.makeOptionalFitsSystemWindows();
先面的是将tilte设置到mDecor中的title view中,以及设置actionBar
........................................
// Post the panel invalidate for later; avoid application onCreateOptionsMenu
// being called in the middle of onCreate or similar.
mDecor.post(new Runnable() {
public void run() {
// Invalidate if the panel menu hasn't been created before this.
PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, false);
if (!isDestroyed() && (st == null || st.menu == null)) {
invalidatePanelMenu(FEATURE_ACTION_BAR);
}
}
});
View的post方法:Causes the Runnable to be added to the message queue.
* The runnable will be run on the user interface thread
public boolean post(Runnable action) {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
return attachInfo.mHandler.post(action);
}
// Assume that post will succeed later
ViewRootImpl.getRunQueue().post(action);
return true;
}
}
}
}
}