返回

Android 系统源码分析之 View 绘制流程 - setContentView()

Android

正文

在 Android 系统源码中,View 绘制流程是一个庞大而复杂的体系,其中涉及到大量类、方法和过程。setContentView() 方法是其中一个关键方法,它负责将一个视图添加到 Activity 的布局中,并触发后续的视图绘制流程。在本文中,我们将深入剖析 setContentView() 方法,从 PhoneWindow.setContentView() 到 DecorView.setContentView(),再到 LinearLayout 布局的应用,为你揭开 Android 系统源码中 View 绘制流程的神秘面纱。

一、PhoneWindow.setContentView():Activity 布局的起点

setContentView() 方法的入口是 PhoneWindow.setContentView()。PhoneWindow 是 Activity 的一个私有内部类,负责管理 Activity 的窗口。PhoneWindow.setContentView() 方法的作用是将一个视图添加到 Activity 的布局中。

当调用 setContentView() 方法时,PhoneWindow 会创建一个 DecorView 对象,并将其作为 Activity 的根视图。DecorView 是一个 FrameLayout 的子类,它负责管理 Activity 的布局。DecorView 的创建过程如下:

private void installDecor() {
    DecorView decor = (DecorView) mLayoutInflater.inflate(
            com.android.internal.R.layout.decor_content_parent, null);
    decor.setWindow(this);
    if (mDecor == null) {
        mDecor = decor;
        mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
        mDecor.setId(android.R.id.content);
        mDecor.setFocusable(false);
        mDecor.setFocusableInTouchMode(false);
        if (mForceDecorInstall != null) {
            decor.addView(mForceDecorInstall);
        }
        mLayoutInflater.runEnterAnimation();
    } else {
        if (mForceDecorInstall != null) {
            mDecor.addView(mForceDecorInstall);
        } else {
            View oldContentView = mDecor.getChildAt(0);
            DecorContentParent newParent =
                    (DecorContentParent) decor.getChildAt(1);
            newParent.setWindow(this);
            mDecor.removeAllViews();
            mDecor.addView(newParent);
            newParent.addView(oldContentView);
            mDecor.requestLayout();
            oldContentView.requestLayout();
        }
    }
    mDecor.requestFocus();
}

从这段代码中可以看出,DecorView 的创建过程主要包括以下几个步骤:

  1. 创建一个 DecorView 对象。
  2. 将 DecorView 设置为 Activity 的根视图。
  3. 设置 DecorView 的各种属性,包括焦点、可点击等。
  4. 将要添加的视图添加到 DecorView 中。
  5. 请求 DecorView 重新布局。

二、DecorView.setContentView():视图绘制流程的枢纽

DecorView.setContentView() 方法是 View 绘制流程的枢纽。它负责将一个视图添加到 DecorView 中,并触发后续的视图绘制流程。

当调用 DecorView.setContentView() 方法时,DecorView 会执行以下步骤:

  1. 创建一个 LinearLayout 布局,并将其作为 DecorView 的子视图。
  2. 将要添加的视图添加到 LinearLayout 布局中。
  3. 请求 DecorView 重新布局。

LinearLayout 布局是一个非常重要的布局,它负责管理 DecorView 中的视图。LinearLayout 布局可以分为垂直布局和水平布局两种,可以通过 orientation 属性来设置。

三、LinearLayout 布局:视图排列的基石

LinearLayout 布局是 Android 系统中使用最广泛的布局之一。它可以将多个视图按垂直或水平方向排列,并可以设置各个视图之间的间距。

LinearLayout 布局的属性如下:

  • orientation:布局方向,可以是垂直布局或水平布局。
  • layout_width:布局宽度,可以是固定值、填充父容器或包裹内容。
  • layout_height:布局高度,可以是固定值、填充父容器或包裹内容。
  • weight:权重,可以控制视图在布局中所占的比例。
  • gravity:对齐方式,可以控制视图在布局中的位置。

四、结语

setContentView() 方法是 Android 系统源码中 View 绘制流程的关键方法之一。它负责将一个视图添加到 Activity 的布局中,并触发后续的视图绘制流程。通过剖析 PhoneWindow.setContentView()、DecorView.setContentView() 和 LinearLayout 布局的应用,我们可以更深入地理解 Android 系统源码和 View 绘制流程。