I know everyone is very hate to read other people write source analysis, because at every turn on long talk, do not speak of martial arts, so appropriate, so inappropriate. So, this is a different source analysis, if you still do not understand after reading. Young man, I advise you:

The introduction

Do you know what’s going on inside a normal actively-setContentView ()?

The profile

Source code analysis

Let’s first look at the activity-setContentView method:

public void setContentView(@LayoutRes int layoutResID) {
    getWindow().setContentView(layoutResID);
    initWindowDecorActionBar();
}
Copy the code

Simply drop method, the internal call getWindows. The setContentView (XXX)

Wait, what is Windows?

Windows represents the concept of a window. In Android, whether it is an Activity, a Dialog, or a Toast, their views are attached to Windows, so Windows can be called the direct manager of the View. Windows has only implementation classes, PhoneWindows.


Let’s go to PhoneWindows setContentView()

@Override
public void setContentView(int layoutResID) {
    if (mContentParent == null) {
        installDecor(); / / concerns
    } else if(! hasFeature(FEATURE_CONTENT_TRANSITIONS)) { mContentParent.removeAllViews(); } mLayoutInflater.inflate(layoutResID, mContentParent); }Copy the code

Simply, a judgment is performed internally and the **installDecor() ** method is called.

Wait, what is mContenParent?

MContentParent is the container that holds our own layout. You can think of it as our root container. See the diagram for more details.


Let’s go look at the installDecor.

private void installDecor(a) {... Ignore mDecor = generateDecor(-1); // Concern 1. ignoreif (mContentParent == null) {
      // Focus 2mContentParent = generateLayout(mDecor); }... Ignore a large section of}Copy the code

This method is very tedious inside, very smelly and very long, do we need to pay attention to so much, no, so directly into generateDecor().

Wait, what is mDecor?

MDecor is the only view for Windows, which is the father of our mContentParent. DecorView for short, if you recall something.


We went on to see the generateDecor() method

protected DecorView generateDecor(int featureId) {... Ignore a large sectionreturn new DecorView(context, featureId, this, getAttributes());
}
Copy the code

This method is just a DecorView, and nothing else. Go back to the point 2-generateLayout() in installDecor().


We go into the generateLayout() method:

protected ViewGroup generateLayout(DecorView decor) {
   / / 1
   TypedArray a = getWindowStyle();
   if(xx)else if(xxx)	
   else {
       layoutResource = R.layout.screen_simple;
   }
   / / 2mDecor.onResourcesLoaded(mLayoutInflater, layoutResource); . Ignore part of it/ / 3
   ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
   return contentParent;
}
Copy the code
  1. The display gets the current theme and starts to determine which layout to use
  2. Load it into the DecorView
  3. Get the R.I.D.C. Tent via findViewById(internally, decorView.findViewById) and return the viewGroup.

Wait, what’s this R.layout.screen_simple?

This is the layout of our DecorView.

As shown above, our layout will eventually be added to the root layout content.

Run your train of thought

Let’s go through the above analysis as a whole:

  • When we call an Activity’ssetContentViewWhen the internal is actually executedPhoneWindows(unique instance of Windows)setContenView()
  • whilePhoneWindowssetContentView()The interior will first determine whether there is a layout containercontentParentThat is, whether or not there isDecorViewIf not, executeinstallDecor()To initialize ourDecorViewwithcontentParent;
  • ininstallDecor() method, will first determine whetherDecorViewIf it doesn’t, new it out first and then see if it doesContentParent (ViewGroup to host our own layout)If not, select a layout based on the current theme and add it as our root layoutDecorViewRd.tent, rD.tent, rD.tent, rD.tent, rD.tentcontentParent;
  • The last PhoneWindows –setContentView()Method then we can make our own layoutinflateInto this root layoutcontentParentIn the;