Android源码如何给Activity渲染布局

    相信做Android应用的一些程序猿,虽然做了几个项目,但是可能还不知道我们Android系统如何给Activity渲染布局的,今天我不要脸地简单介绍一下,也算自己学习记录一下。

我们都知道,我们自己创建了XXActivity会去继承系统的Activity类,也知道Activity是通过setContentView()这个方法把布局渲染进去的。在Activity类中,我们可以找到这个方法:

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

从这个方法分析,getWindow()是返回一个Window对象,我们找到Window类,在这个类中我们可以发现这个抽象方法:
public abstract void setContentView(@LayoutRes int layoutResID);
从而我们可以知道一定有一个类去继承Window这个抽象类并实现setContentView()这个方法,那么究竟是哪个类去继承它呢?上面说到在Activity类中获取Window对象可以直接调用getWindow(),从而推知在Activity类中必然也会有去创建Window这个实现类,通过查找可发现:

mWindow = new PhoneWindow(this, window);

这个时候我们就知道PhoneWindow必是Window的实现类,那么再来查找PhoneWindow这个类,通过全局查找并未找到这个类,那这个类究竟放在哪里呢?这个时候我们想到去sdk里面查找,果不其然,可以找到这个类。那么我们在PhoneWindow这个类中再去找setContentView()
这个方法的实现,如下:
    @Override
    public void setContentView(int layoutResID) {
        // Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window
        // decor, when theme attributes and the like are crystalized. Do not check the feature
        // before this happens.
        if (mContentParent == null) {
            installDecor();
        } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
            mContentParent.removeAllViews();
        }


        if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
            final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,
                    getContext());
            transitionTo(newScene);
        } else {
            mLayoutInflater.inflate(layoutResID, mContentParent);
        }
        mContentParent.requestApplyInsets();
        final Callback cb = getCallback();
        if (cb != null && !isDestroyed()) {
            cb.onContentChanged();
        }
        mContentParentExplicitlySet = true;
    }


打开mLayoutInflater.inflate(layoutResID, mContentParent)这句代码关联,跳到LayoutInflater类中:
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) {
        return inflate(resource, root, root != null);
    }
再点开inflate(resource, root, root != null),跳到下面这个方法中:
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot) {
         final Resources res = getContext().getResources();
        if (DEBUG) {
            Log.d(TAG, "INFLATING from resource: \"" + res.getResourceName(resource) + "\" ("
                    + Integer.toHexString(resource) + ")");
        }


        final XmlResourceParser parser = res.getLayout(resource);
        try {
            return inflate(parser, root, attachToRoot);
        } finally {
            parser.close();
        }
    }
在这个方法中我们可以发现final XmlResourceParser parser = res.getLayout(resource);这是xml资源文件的解析器,然后再点开return inflate(parser, root, attachToRoot),如下:
public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) {......}
最终是调用这个方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值