面试之-setContentView (View被添加到Dect

2022-06-28  本文已影响0人  雨来

这个是26版本的源码啊

1、Activity setContentView

image.png

getWindow().setContentView(layoutResID);

getWindow 返回的是window

image.png

而Window是一个抽象类


image.png

它有一个唯一的实现类 是phoneWindow

phoneWindow的setContentView


image.png

installDecor方法

image.png

generateDecor 返回了一个DectorView


image.png

我们要知道 这个 DectorView是一个FrameLayout


image.png

genratelayout 方法

image.png

在其方法内部有这个方法 (onResoureLoaded )


image.png

通过上面 generateDecor 生成的DectorView 传过来 调用

 mDecor.onResourcesLoaded(mLayoutInflater, layoutResource);

我们看一下 onResourcesLoaded 方法 同时注意一个 layoutResource 这个参数

layoutResource 这个参数的取值是 一个布局文件 layout 是系统定义的 (通这上面不用的feature(them)来确定的)比如有没有actionBar
我们发现在它有一个addView的动作


image.png

这里我们要确定这个root是谁 (这个root就是系统布局通过inflate 生成的View)


image.png
addView(root, 0, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));

这个addView 是 DectorView调用的

也就是说方法走到这里 DectorView 调用了一次addView 而添加的View还是系统的布局 还不是我们setContentView的 layoutId呢

我们在看这里 findViewById(ID_ANDROID_CONTENT) (距离真相越来越近了)
protected ViewGroup generateLayout(DecorView decor) {
        ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
        return contentParent;
    }
   //在这里找到  id 是  ID_ANDROID_CONTENT 的 layout 当然这个 id 是 存在于 layoutResource 中的
        ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);

我们发现在 generateLayout 是把 ID_ANDROID_CONTENT 是ViewGroup返回了

ok我们返回到 PhoneWindow的setContentView

看一下mContentParent是在哪里赋值的?

image.png

也就是说 这个mContentParent是通过 genrateLayout这个方法生成的

这句话很重要

mContentParent 是DectorView(添加了系统定义的layout布局)中 id 是 ID_ANDROID_CONTENT 的ViewGroup


image.png

然后通过inflate 把布局添加到 id 是 ID_ANDROID_CONTENT 的ViewGroup中

image.png
image.png
上一篇 下一篇

猜你喜欢

热点阅读