Activity的setContentView源码阅读

Activity.java

    public void setContentView(@LayoutRes int layoutResID) {
        //activity的setContentView
        getWindow().setContentView(layoutResID);
    }

点击setContentView

    //发现是抽象方法.表示有子类实现了这个方法.
    public abstract void setContentView(@LayoutRes int layoutResID);

getWindow调用的setContentView.我们来看一下getWindow()方法.

    public Window getWindow() {
        return mWindow;
    }

看哪里实例化.找到了实例化的地方.看到PhoneWindow.我们找到PhoneWindow这个类看它实现的setContentView方法

mWindow = new PhoneWindow(this, window, activityConfigCallback);

phoneWindow.java
查看phoneWindow的setContentView方法.

    @Override
    public void setContentView(int layoutResID) {
        if (mContentParent == null) {
            // 如果mContentParent 等于空,调用installDecor();生成DecorView
            installDecor();
        } 
            // 把我们自己的布局layoutId加入到mContentParent,我们set进来的布局原来是放在这里面
            mLayoutInflater.inflate(layoutResID, mContentParent);
    }

查看installDecor方法

private void installDecor() {
        if (mDecor == null) {
            //如果mDecor 为空,创建DecorView
            mDecor = generateDecor();
        }
        if (mContentParent == null) {
            //生成Layout
            mContentParent = generateLayout(mDecor);
        }
}
    //创建DecorView
    protected DecorView generateDecor() {
        return new DecorView(getContext(), -1);
    }

//DecorView是一个FrameLayout
private final class DecorView extends FrameLayout 
    /**
     * The ID that the main layout in the XML layout file should have.
     */
    public static final int ID_ANDROID_CONTENT = com.android.internal.R.id.content

    protected ViewGroup generateLayout(DecorView decor) {
     // Inflate the window decor.
        int layoutResource;
        //做了一系列判断,去加载系统Layout资源
        layoutResource = R.layout.screen_simple;
        
        //解析实例化系统的布局
        View in = mLayoutInflater.inflate(layoutResource, null);
        //把系统的布局加入到DecorView中.
        decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
        //找一个叫做anroid.R.id.context的FrameLayout
        ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
        //返回叫做anroid.R.id.context的FrameLayout
        return contentParent;
   }

screen_simple.xml
系统布局


    
    

setContentView() 系统到底把我们的布局加到哪里去了。我先用文字总结一下,然后去画一张图:

1.Activity里面设置setContentView(),我们的布局显示主要是通过PhoneWindow,PhoneWindow获取实例化一个DecorView。
2.实例化DecorView,然后做一系列的判断然后去解析系统的资源layoutId文件,把它解析加载到DecorView,资源layout里面有一个View的id是android.R.id.content.
3.我们自己通过setContentView设置的布局id其实是解析到mParentContent里面的,也就是那个id叫做android.R.id.content的FarmeLayout。

Activity的setContentView源码阅读_第1张图片

你可能感兴趣的:(Activity的setContentView源码阅读)