Android loading process analysis (setContentView layout loading)

This article mainly describes how the app onCreateis called in the method setContentViewto load the layout. For those who want to know setContentViewthe 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 setContentViewmethod

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, PhoneWindowthe setContentViewmethods 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 layoutResIDinto the rootview mContentParent, so mContentParenthow 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 mDecorand mContentParenttwo objects

// This is the top-level view of the window, containing the window decor.
private DecorView mDecor;

Looking mDecorat the description, you can see that this is the top-level view of the window. Note that it is DecorViewinherited from FrameLayoutand 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 mContentParentat the description, you can see that this is the parent layout of the view, which can be the top-level layout mDecoritself, 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 layoutResourceof assignment logic is omitted in the middle , as can be seen from the above, mDecorcall onResourcesLoadedto 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 layoutResourcelayout, while the obtained view(root) bind to itself ( DecorView), mDecorCaptionViewonly root, and DecorViewthe intermediate layer, essentially rootbound to DecorView.
Through mDecor.onResourcesLoaded(mLayoutInflater, layoutResource), mDecorrendering the basic layout, a layout of the id of the presence contentof FrameLayoutthe container (the container to view the area to place apk, usually we new project main_acvitityis placed here), as shown below
Insert picture description here
after executing onResourcesLoadedAfter PhoneWindowbuiltcontentParent

//ID_ANDROID_CONTENT: com.android.internal.R.id.content
ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);

At this point, I suddenly realized that this contentParentis the parent view of the apk view. Finally, generateLayoutthe parent view is returned and assigned tomContentParent

mContentParent = generateLayout(mDecor)

The next step is to DecorViewdo some initialization operations on some of the default views, so I won’t go into too much description, jump out installDecorto see the next key point

mLayoutInflater.inflate(layoutResID, mContentParent)

At this point, it is very clear. The first step installDecoris 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

Guess you like

Origin blog.csdn.net/weixin_48968045/article/details/114504440