Activity中布局资源layoutResId在setContentView加载过程分析

本文详细分析了Android中Activity的setContentView方法在加载布局资源时的执行过程,从寻找setContentView的真正实现,到mWindow的实例化,再到PhoneWindow中的setContentView实现。内容包括布局解析、installDecor方法、generateLayout方法的探讨,以及布局资源screen_title.xml的解析。通过对整个流程的剖析,加深了对Android视图加载机制的理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

记得刚开始学习安卓那会,感觉安卓真的很简单,用xml写一个布局,然后再写一个activity,接着调用一下在onCreate中调用下setContentView(resId)一个页面就可以看到了,现在回想也才知道Android的牛逼,它降低了开发者的门槛 ,但是一旦你跨过门槛,越往里走就发现越神奇,下面就分析下setContentView(resId)中到底做了什么,也是为了后面分析view的Measure过程做一个铺垫。

分析

1、寻找setContentView真正实现的地方

一般我们在新建的activity中传入布局的id就可以加载这个页面了,当然setContentView有几个重载的方法,就不细说了。

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

上面讲到了activity的onCreate方法,很明显onCreate方法中我们常用的就是调用setContentView来给activity给定一个显示的布局id,就是我们常继承的Activity中的setContentView(resId)的源码

      /**
     * Set the activity content from a layout resource.  The resource will be
     * inflated, adding all top-level views to the activity.
     *
     * @param layoutResID Resource ID to be inflated.
     * 准备导入的布局资源的id
     * @see #setContentView(android.view.View)
     * @see #setContentView(android.view.View, android.view.ViewGroup.LayoutParams)
     */
    public void setContentView(int layoutResID) {
        getWindow().setContentView(layoutResID);
        //ActionBar的初始化,平时很少用ActionBar暂时忽略
        initActionBar();
    }

2、mWindow实例化

getWindow返回的是mWindow,mWindow是窗口抽象类Window的一个实例,而setContentView(resId)是window中一个抽象方法,所以我们需要找到mWindow实例化的地方,然后看mWindow实现类的setContentView方法做了一些什么工作。

final void attach(Context context, ActivityThread aThread,
            Instrumentation instr, IBinder token, int ident,
            Application application, Intent intent, ActivityInfo info,
            CharSequence title, Activity parent, String id,
            NonConfigurationInstances lastNonConfigurationInstances,
            Configuration config) {
        attachBaseContext(context);
    ...
         mWindow = PolicyManager.makeNewWindow(this);
    ...

最后在activity的attach方法中找到了mWindow实例化的地方,接着需要找PolicyManager.makeNewWindow返回的对象,也就是Window实现子类,PolicyManager的代码不多,所以这里就直接贴出来了看看。

/**
 * 隐藏的api,难怪sdk中找不到。T—T
 * {@hide}
 */
public final class PolicyManager {
   
    private static final String POLICY_IMPL_CLASS_NAME =
        "com.android.internal.policy.impl.Policy";
    private static final IPolicy sPolicy;
    static {
        // Pull in the actual implementation of the policy at run-time
        try {
            Class policyClass = Class.forName(POLICY_IMPL_CLASS_NAME);
            sPolicy = (
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值