返回

Android布局绘制流程二:setContentView源码解读

Android

Android 布局绘制揭秘:剖析 setContentView 的源码原理

在 Android 开发中,setContentView 函数扮演着至关重要的角色,负责为 Activity 设置布局视图。它将用户界面 (UI) 元素渲染到屏幕上,为应用程序提供视觉界面。本文将深入剖析 setContentView 的源码,揭开 Android 布局绘制的底层原理。

setContentView 的核心逻辑

setContentView 函数的核心逻辑发生在 DecorView 类中,它是 Activity 中用于绘制内容的根视图。DecorView 有两个关键成员变量:

  • View mContentView: 当前 Activity 的根视图
  • ViewGroup mDecorContentParent: 负责管理 mContentView 的父视图组

setContentView 函数主要执行以下步骤:

  1. 检查 mContentView 是否为空,如果为空则移除旧的根视图。
  2. 将新的视图(通过 findViewById 获取)设置给 mContentView
  3. mContentView 添加到 mDecorContentParent

绘制流程

setContentView 完成设置后,Android 系统会启动绘制流程:

  1. ViewRootImpl.performTraversals : 绘制流程的入口,首先进行测量和布局。
  2. View.measure : 测量每个视图的尺寸,并确定其子视图的布局参数。
  3. View.layout : 根据布局参数,确定每个视图的最终位置和大小。
  4. View.draw : 根据布局信息,绘制视图的内容。
  5. ViewRootImpl.draw : 最后,将所有视图绘制到屏幕上。

源码分析

深入源码,让我们进一步了解绘制流程:

@Override
public void setContentView(View view) {
    // 检查mContentView是否为空
    if (mContentView != null) {
        // 移除旧的根视图
        mDecorContentParent.removeView(mContentView);
    }
    // 设置新的根视图
    mContentView = view;
    // 将根视图添加到父视图组
    mDecorContentParent.addView(mContentView, 0);
}

@Override
public boolean performTraversals() {
    // 进行测量和布局
    measureTree();
    layoutTree();
    // 准备绘制
    prepareTree();
    // 将所有视图绘制到屏幕上
    drawTree();
    return true;
}

setContentView 中,performTraversals 方法被调用,它将依次执行测量、布局、准备和绘制阶段。

测量阶段

在测量阶段,Android 系统会根据父视图组的尺寸和布局参数,确定每个视图的测量尺寸。Viewmeasure 方法会被调用,它将计算视图的测量宽度和高度。

布局阶段

在布局阶段,Android 系统会根据测量尺寸和布局参数,确定每个视图的最终位置和大小。Viewlayout 方法会被调用,它将根据父视图组的布局规则,计算视图的最终布局位置。

准备阶段

在准备阶段,Android 系统会为绘制做准备。它会计算每个视图的绘制边界,并为每个视图分配内存缓冲区。

绘制阶段

在绘制阶段,Android 系统会根据布局信息,将每个视图的内容绘制到屏幕上。Viewdraw 方法会被调用,它将根据绘制边界,使用 canvas 绘制视图的内容。

结论

通过对 setContentView 函数的源码分析,我们深入了解了 Android 布局绘制流程的底层原理。该流程包括测量、布局、准备和绘制四个阶段,每个阶段都有其独特的任务。掌握这些原理对于构建和优化 Android 应用程序的 UI 至关重要。

常见问题解答

  1. 什么是 DecorView
    DecorView 是 Activity 中绘制内容的根视图,它包含根视图和管理根视图的父视图组。

  2. setContentView 函数做了什么?
    setContentView 函数将新的布局视图设置给 Activity,并将根视图添加到 Activity 的根视图组中。

  3. 测量阶段做了什么?
    测量阶段计算每个视图的测量尺寸,根据父视图组的尺寸和布局参数。

  4. 布局阶段做了什么?
    布局阶段确定每个视图的最终位置和大小,根据父视图组的布局规则和测量尺寸。

  5. 绘制阶段做了什么?
    绘制阶段根据布局信息将视图内容绘制到屏幕上。它调用视图的 draw 方法,使用 canvas 绘制内容。