This article mainly describes how the app onCreate
is called in the method setContentView
to load the layout. For those who want to know setContentView
the execution logic of the app from startup to execution , you can view the Android loading process analysis (from app startup to execution onCreate
) .
First look at the setContentView
method
public void setContentView(@LayoutRes int layoutResID) {
getWindow().setContentView(layoutResID); //1
initWindowDecorActionBar(); //2
}
As can be seen from the name, 1 performed the loading of the view, 2 was initialized ActionBar
, and viewed 1, PhoneWindow
the setContentView
methods that can be traced :
public void setContentView(int layoutResID) {
if (mContentParent == null) {
installDecor(); //1
}
...
if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
...
} else {
mLayoutInflater.inflate(layoutResID, mContentParent); //2
}
...
}
It can be inferred from the name that 1 performs some initialization work, and 2 is the real operation of dynamically loading the view. Inflate is dynamically loaded layoutResID
into the root
view mContentParent
, so mContentParent
how does this come from, and what kind of view is it? **Leave this question and continue to see what work has been done:
private void installDecor() {
if (mDecor == null) {
mDecor = generateDecor(-1);
...
} else {
mDecor.setWindow(this);
}
if (mContentParent == null) {
mContentParent = generateLayout(mDecor);
...
}
...
}
Here need attention mDecor
and mContentParent
two objects
// This is the top-level view of the window, containing the window decor.
private DecorView mDecor;
Looking mDecor
at the description, you can see that this is the top-level view of the window. Note that it is DecorView
inherited from FrameLayout
and is also aViewGroup
// This is the view in which the window contents are placed. It is either
// mDecor itself, or a child of mDecor where the contents go.
ViewGroup mContentParent;
Looking mContentParent
at the description, you can see that this is the parent layout of the view, which can be the top-level layout mDecor
itself, or the subview below
protected ViewGroup generateLayout(DecorView decor) {
...
int layoutResource;
// System.out.println("Features: 0x" + Integer.toHexString(features));
if ((features & (1 << FEATURE_SWIPE_TO_DISMISS)) != 0) {
layoutResource = R.layout.screen_swipe_dismiss;
setCloseOnSwipeEnabled(true);
} else if ((features & ((1 << FEATURE_LEFT_ICON) | (1 << FEATURE_RIGHT_ICON))) != 0) {
...
}
mDecor.onResourcesLoaded(mLayoutInflater, layoutResource);
...
return contentParent;
}
A lot layoutResource
of assignment logic is omitted in the middle , as can be seen from the above, mDecor
call onResourcesLoaded
to show the top-level layout, viewonResourcesLoaded
void onResourcesLoaded(LayoutInflater inflater, int layoutResource) {
...
mDecorCaptionView = createDecorCaptionView(inflater);
final View root = inflater.inflate(layoutResource, null);
if (mDecorCaptionView != null) {
if (mDecorCaptionView.getParent() == null) {
addView(mDecorCaptionView,
new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
}
mDecorCaptionView.addView(root,
new ViewGroup.MarginLayoutParams(MATCH_PARENT, MATCH_PARENT));
} else {
// Put it below the color views.
addView(root, 0, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
}
mContentRoot = (ViewGroup) root;
...
}
The method for dynamic loading layoutResource
layout, while the obtained view
(root) bind to itself ( DecorView
), mDecorCaptionView
only root
, and DecorView
the intermediate layer, essentially root
bound to DecorView
.
Through mDecor.onResourcesLoaded(mLayoutInflater, layoutResource)
, mDecor
rendering the basic layout, a layout of the id of the presence content
of FrameLayout
the container (the container to view the area to place apk, usually we new project main_acvitity
is placed here), as shown below
after executing onResourcesLoaded
After PhoneWindow
builtcontentParent
//ID_ANDROID_CONTENT: com.android.internal.R.id.content
ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
At this point, I suddenly realized that this contentParent
is the parent view of the apk view. Finally, generateLayout
the parent view is returned and assigned tomContentParent
mContentParent = generateLayout(mDecor)
The next step is to DecorView
do some initialization operations on some of the default views, so I won’t go into too much description, jump out installDecor
to see the next key point
mLayoutInflater.inflate(layoutResID, mContentParent)
At this point, it is very clear. The first step installDecor
is to confirm the global root view, perform the initialization operation, and return to the position of the apk view at the same time mContentParent(ViewGroup)
. The next task is to dynamically load the apk view ( layoutResID
) and bind it to the corresponding In the parent container ( mContentParent
)
Reference link: https://www.jianshu.com/p/0f6b4bc86c7b