Source code analysis | activity setcontentview I don't flash

Posted by slawrence10 on Wed, 09 Feb 2022 10:07:26 +0100

I know that everyone hates reading the source code analysis written by others, because they often talk at length and don't talk about martial ethics. Is this appropriate? It's not appropriate. Therefore, this is a different source code analysis. If you don't understand it after reading it.

introduction

An ordinary activity setcontentview (), do you know what it does internally?

outline

Source code analysis

Let's take a look at the activity setcontentview method first:

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

Simple drop method, internal call to getwindows setContentView(xxx)

Wait, what is Windows?

Windows represents the concept of a window. In Android, no matter Activity,dialog or Toast, their views are attached to windows. Therefore, windows can be called the direct manager of View. Windows has only implementation classes, that is, PhoneWindows

Let's go to the setContentView() of PhoneWindows

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

Simply execute a judgement internally, then call the **installDecor() * method.

Wait, what is mContenParent?

mContentParent is the container for placing our own layout. You can understand that it is our root layout. See the figure for details.

Let's next look at the installDecor() method:

private void installDecor() {
  	...Ignore
    mDecor = generateDecor(-1); //Focus 1
  	...Ignore
  	if (mContentParent == null) {
      //Focus 2
      mContentParent = generateLayout(mDecor);
    }
  	...Ignore a large paragraph
}

This method is cumbersome, smelly and long. Do we need to pay so much attention? No, so go directly to generateDecor()

Wait, what's mDecor?

mDecor is the only view of windows, that is, the father of our mContentParent. DecorView for short, does it recall something.

Let's move on to the generateDecor() method

protected DecorView generateDecor(int featureId) {
  	...Ignore a large paragraph
    return new DecorView(context, featureId, this, getAttributes());
}

Wow, this method is in love. It directly creates a DecorView and nothing else. Go back to the focus 2-generateLayout() in installDecor()

We enter the generateLayout() method:

protected ViewGroup generateLayout(DecorView decor) {
   //1
   TypedArray a = getWindowStyle();
   if(xx)else if(xxx)	
   else {
       layoutResource = R.layout.screen_simple;
   }
   //2
   mDecor.onResourcesLoaded(mLayoutInflater, layoutResource);
	 ..Ignore some
   //3
   ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
   return contentParent;
}
  1. The display gets the current theme, and then starts to determine which layout to use
  2. Load it into DecorView
  3. Get R.id.content through findviewbyid (internally DecorView.findViewById) and return this viewGroup.

Wait, this r.layout screen_ What is simple?

Oh, just an ordinary layout, nothing too strange.

Train of thought

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

  • When we call setContentView of Activity, the internal is actually the setContentView() of phonewindows (the only instance of windows);
  • The setContentView() of PhoneWindows will first judge whether there is a root layout contentParent, that is, whether there is a DecorView. If not, execute installDecor() to initialize our DecorView and contentParent;
  • In the installDecor() method, we will first judge whether there is a DecorView. If not, we will first create a new one, and then judge whether there is a contentParent. If not, we will select a layout according to the current theme and add it to the DecorView as our root layout;
  • Finally, the phonewindows setcontentview () method can then inflate our own layout into the root layout;