Activity、Window和View三者间的关系【Android】

本文详细解析了Android Activity如何通过PhoneWindow展示视图的过程,从Activity的attach方法开始,阐述了如何创建PhoneWindow,进而调用setContentView方法来填充视图。文章深入探讨了各关键步骤及三者之间的关系,包括如何通过Window对象和PhoneWindow来展示Activity内容,以及如何在Activity中使用setContentView方法来加载布局文件。

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

一、如何将Activity展现在手机上

        Tips:Activity本身是没办法处理显示什么控件(view)的,是通过PhoneWindow进行显示的 , 换句话说:activity就是在造PhoneWindow,显示的那些view都交给了PhoneWindow处理显示.

1、在Activity创建时调用attach方法:
2、attach方法中会调用PolicyManager.makeNewWindow()  ,  实际工作的是IPolicy接口的makeNewWindow方法
      ①、其中创建了一个window(可以比喻为一个房子上造了一个窗户):mWindow = PolicyManager.makeNewWindow(this);
      ②、在window这个类中,才调用了setContentView(),这是最终的调用
             在Activity的setContentView方法中,实际上是调用:getWindow().setContentView(view, params);
             这里的getWindow()就是获取到一个Window对象
Tips:
       为啥attch优先于onCreate调用,就是由于在attch方法中,会创建window,有了window才能调用setContentView
3、在IPolicy的实现类中创建了PhoneWindow:
      ①、由mWindow = PolicyManager.makeNewWindow(this);,
      ②、这里的makeNewWindow(this);方法中,返回的是:return sPolicy.makeNewWindow(context);
      ③、这个sPolicy实际是一个接口,其实现类是Policy,其中只是创建了一个PhoneWindow
4、在PhoneWindow的setContentView中向ViewGroup(root)中添加了需要显示的内容
      ①、PhoneWindow是继承Window的
      ②、setContentView这个方法中,需要先判断一个mContentParent是否为空,因为在默认进来的时候,什么都没创建呢
             此时需要创建:installDecor(),DecorView是最根上的显示的
             可以通过adt中的的tools中有个hierarchyviewer.bat的工具,可以查看手机的结构
③、DecorView:是继承与FrameLayout的,作为parent存在,最初显示的
④、下次再加载的时候,mContentParent就不为空了,会将其中的所有的view移除掉,然后在通过布局填充器加载布局

二、三者关系

1、在Activity中调用attach,创建了一个Window
2、创建的window是其子类PhoneWindow,在attach中创建PhoneWindow
3、在Activity中调用setContentView(R.layout.xxx)
4、其中实际上是调用的getWindow().setContentView()
5、调用PhoneWindow中的setContentView方法
6、创建ParentView:
 作为ViewGroup的子类,实际是创建的DecorView(作为FramLayout的子类)
7、将指定的R.layout.xxx进行填充
通过布局填充器进行填充【其中的parent指的就是DecorView】
8、调用到ViewGroup
9、调用ViewGroup的removeAllView(),先将所有的view移除掉
10、添加新的view:addView()

Tips:
 ①、Activity就是在造“窗户”,即创建PhoneWindow
 ②、PhoneWindow才是进行显示view的操作,主要就是setContentView()




<think>我们正在讨论Android系统中的几个核心概念:ActivityWindowView、SurfaceLayer。它们之关系Android图形显示用户交互的基础。下面我将结合引用内容,逐步解释它们的作用与关联。###1.**Activity**:用户界面的容器-ActivityAndroid应用的基本组件,代表一个用户界面。它负责管理用户交互生命周期。-每个Activity都持有一个**Window**对象(具体实现是`PhoneWindow`)[^1]。Activity通过`setContentView()`方法将布局设置到Window中。###2.**Window**:视图的承载框架-Window是一个抽象类,负责管理顶级视图(即整个窗口的视图层次结构)。它的实现类是`PhoneWindow`。-Window的主要作用:-创建并管理`DecorView`(整个窗口的根视图)[^1]。-作为ActivityView的解耦层,处理窗口属性(如标题栏、背景等)。-Window通过`WindowManager`将视图添加到屏幕上(见下文)。###3.**View**:UI的基本单元-View代表屏幕上的一个矩形区域,负责绘制事件处理[^2]。-ViewGroup是View的子类,用于容纳多个View,形成树状结构(视图树)。-在Activity中,我们通过`setContentView()`设置的布局文件最终会被添加到`DecorView`的`contentParent`区域中(即ContentView)[^1]。###4.**DecorView**:窗口的根视图-它是`PhoneWindow`的内部类,继承自`FrameLayout`。-包含两个部分:-标题栏(可选,由主题决定)-内容区域(`android.R.id.content`),我们设置的布局就放在这里。-因此,`DecorView`是整个视图树的根节点。###5.**ViewRootImpl**:连接ViewWindowManager的桥梁-`ViewRootImpl`负责:-连接视图树`WindowManager`[^3]。-处理视图的测量(measure)、布局(layout)、绘制(draw)三大流程。-将绘制结果同步到`Surface`上。-每个`Window`(即每个Activity)对应一个`ViewRootImpl`实例。###6.**Surface**:绘制的画布-`Surface`是一个由屏幕合成器(SurfaceFlinger)管理的原始缓冲区(RawBuffer)的持有者[^5]。-每个`Window`对应一个`Surface`。当视图需要绘制时,`ViewRootImpl`会通过`Surface`获取一个`Canvas`(画布),然后在上面绘制视图内容。-绘制完成后,`Surface`的内容会被提交给SurfaceFlinger进行合成显示。###7.**Layer**:SurfaceFlinger中的显示单元-在Android的底层显示系统(SurfaceFlinger)中,每个`Surface`对应一个**Layer**(具体类型如`BufferLayer`)[^5]。-Layer是SurfaceFlinger管理的最小显示单元,负责存储像素数据(即窗口内容)并参与合成。-SurfaceFlinger将所有Layer按照Z-order(深度顺序)合成为最终帧,输出到屏幕。---###整体协作流程1.**创建窗口**:当Activity启动时,会创建一个`PhoneWindow`,并初始化`DecorView`。2.**设置内容**:调用`setContentView()`将用户布局添加到`DecorView`的内容区域。3.**连接系统服务**:Activity通过`WindowManager`(实际是`WindowManagerGlobal`)将`DecorView`添加到系统中。此时会创建`ViewRootImpl`[^3]。4.**绘制准备**:`ViewRootImpl`负责初始化`Surface`(通过`Session`与SurfaceFlinger通信)。5.**视图绘制**:-`ViewRootImpl`触发视图树的测量、布局、绘制。-绘制过程中,每个View通过`Canvas`在`Surface`上绘制内容。6.**提交显示**:绘制完成后,`ViewRootImpl`将`Surface`的内容提交给SurfaceFlinger。7.**合成显示**:SurfaceFlinger将属于该窗口的`Layer`与其他Layer(如状态栏、其他App窗口)合成,最终输出到屏幕。---###关系总结|组件|作用|关联对象||---------------|----------------------------------------------------------------------|------------------------------||**Activity**|用户交互的容器|持有`PhoneWindow`||**Window**|管理顶级视图结构窗口属性|持有`DecorView`||**DecorView**|窗口的根视图,包含标题栏内容区域|是`ViewGroup`的子类||**View**|UI的基本单元,负责绘制事件处理|组成视图树||**ViewRootImpl**|连接视图树与`WindowManager`,处理三大流程并管理`Surface`|每个`Window`对应一个实例||**Surface**|绘制的画布,持有图形缓冲区|由`ViewRootImpl`创建管理||**Layer**|SurfaceFlinger中的显示单元,存储窗口像素数据|与`Surface`一一对应[^5]|###示例代码:Activity中视图的添加```javapublicclassMainActivityextendsActivity{@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);//以下操作在PhoneWindow中完成://1.创建DecorView//2.将R.layout.activity_main添加到DecorView的内容区域setContentView(R.layout.activity_main);}}```###§§相关问题§§1.`ViewRootImpl`在何时被创建?2.Surface的缓冲区是如何分配的?3.多个Activity窗口的Layer在SurfaceFlinger中如何排序?4.硬件加速绘制对SurfaceLayer有什么影响?5.DecorView的measure/layout/draw流程是如何触发的?</think>### Android 系统中 Activity、Layer、Surface、Window View关系解析 #### 1. **Activity:用户交互的容器** - **作用**:Android 应用的基本组件,负责管理用户界面生命周期。 - **关联**: - 每个 Activity 持有一个 **Window** 对象(具体实现为 `PhoneWindow`)[^1]。 - 通过 `setContentView()` 将 **View** 树附加到 Window 上。 - **关键流程**: ```java // Activity 创建时初始化 Window public class MainActivity extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 初始化 PhoneWindow setContentView(R.layout.main); // 将 View 附加到 Window } } ``` #### 2. **Window:视图的承载框架** - **作用**:抽象层,管理窗口属性视图层级(如标题栏、背景等),实现类是 `PhoneWindow`[^1]。 - **关联**: - 包含根视图 **DecorView**(继承自 `FrameLayout`)。 - 通过 `WindowManager` 与系统服务通信。 - **关键结构**: ``` Window (PhoneWindow) └── DecorView ├── TitleBar (可选) └── ContentView (用户设置的 View 树) ``` #### 3. **View:UI 的基本单元** - **作用**:屏幕上的矩形区域,负责绘制事件处理[^2]。 - **关联**: - 通过组合模式形成树状结构(`ViewGroup` 管理子 View)。 - 最终由 **ViewRootImpl** 绘制到 **Surface** 上。 - **绘制流程**: `measure()` → `layout()` → `draw()` → 内容写入 Surface 的缓冲区。 #### 4. **Surface:绘制的画布** - **作用**:共享内存中的图形缓冲区,承载 View 的绘制结果[^5]。 - **关联**: - 每个 Window 对应一个 Surface。 - 由 **ViewRootImpl** 通过 `Surface.lockCanvas()` 获取 `Canvas` 对象供 View 绘制。 - **生命周期**: `SurfaceControl.create()` → `Surface.copyFrom()` → 提交给 **SurfaceFlinger**。 #### 5. **Layer:合成的显示单元** - **作用**:SurfaceFlinger 中的最小合成单元,存储像素数据[^5]。 - **关联**: - 与 **Surface 一一对应**(如 `BufferLayer` 对应 App 窗口)。 - SurfaceFlinger 按 Z-order 合成所有 Layer 输出到屏幕。 - **创建流程**: `WindowManagerService` → `SurfaceControl` → `SurfaceFlinger::createBufferLayer()` --- ### 核心协作流程 1. **初始化** Activity 创建 → 初始化 `PhoneWindow` → 构建 `DecorView` `ContentView`[^1]。 2. **视图管理** `WindowManager` 将 `DecorView` 添加到系统 → 创建 `ViewRootImpl`[^3]。 3. **绘制合成** - `ViewRootImpl` 触发 View 树的绘制流程[^2]。 - 通过 `Surface.lockCanvas()` 获取画布,View 绘制到 Surface 缓冲区[^4]。 - `Surface.unlockCanvasAndPost()` 提交缓冲区。 - SurfaceFlinger 将对应的 **Layer** 合成到屏幕[^5]。 ```mermaid graph LR A[Activity] --> B[Window] B --> C[DecorView] C --> D[View Tree] D --> E[ViewRootImpl] E --> F[Surface] F --> G[SurfaceFlinger Layer] ``` ### 关键关系总结 | 组件 | 依赖关系 | 通信机制 | |-------------|----------------------------------|-----------------------| | Activity | 持有 Window 实例 | 直接调用 | | Window | 持有 DecorView ViewRootImpl | 跨进程通信(Binder) | | View | 依附于 Window 的视图树 | 绘制指令 | | Surface | 被 ViewRootImpl 管理 | 共享内存 + Binder | | Layer | 与 Surface 一一对应 | SurfaceFlinger 内部管理 | ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值