当前位置: 首页 > news >正文

Android Framework学习二:Activity创建及View绘制流程

文章目录

  • Window绘制流程
    • Window Manager Service(WMS)
    • Surface
    • SurfaceFlinger
  • 安卓View层次结构
    • Activity
    • PhoneWindow
    • Activity与PhoneWindow两者之间的关系
    • ViewRootImpl
    • DecorView
      • DecorView 的作用
      • DecorView 的结构
      • 总结
  • Activity创建流程
  • View invalidate调用流程

Window绘制流程

在这里插入图片描述
在安卓系统中,Window Manager Service(WMS)和 Surface 是与窗口管理和图形显示相关的重要概念。

Window Manager Service(WMS)

  • 功能概述:WMS 是安卓系统中负责管理窗口的系统服务。它主要负责窗口的创建、销毁、布局、显示顺序以及与用户交互等方面的管理。
  • 工作原理:当一个应用程序创建一个窗口(例如 Activity 的界面)时,它会向 WMS 发送请求。WMS 会为该窗口分配一个唯一的标识,并根据窗口的属性(如大小、位置、层级等)将其添加到窗口管理列表中。在绘制窗口时,WMS 会协调各个窗口的位置和显示顺序,确保它们按照正确的方式显示在屏幕上。当用户进行触摸屏幕等交互操作时,WMS 会根据触摸事件的位置和窗口的布局,将事件分发给相应的窗口进行处理。

Surface

  • 概念:Surface 是安卓图形系统中的一个重要概念,它代表了一个可绘制的区域,用于在屏幕上显示图形内容。可以将 Surface 看作是一块画布,应用程序可以在上面绘制各种图形、图像和文本等内容。
  • 作用:每个窗口都有一个或多个 Surface 与之关联。当应用程序需要绘制窗口的内容时,它会通过 Surface 来获取绘图的上下文,然后使用图形库(如 OpenGL)在 Surface 上进行绘制。绘制完成后,Surface 会将绘制的结果提交给系统的图形合成器(通常是 Surface Flinger),由图形合成器将各个窗口的 Surface 进行合成,最终显示在屏幕上。
  • 与 WMS 的关系:WMS 负责管理窗口的整体布局和显示顺序,而 Surface 则是窗口内容绘制的载体。WMS 会根据窗口的状态和用户的操作,通知应用程序更新其 Surface 的内容。例如,当窗口大小发生变化时,WMS 会通知应用程序重新绘制 Surface 以适应新的大小。同时,WMS 也会与 Surface Flinger 协作,确保各个 Surface 能够按照正确的顺序和方式进行合成和显示。

SurfaceFlinger

SurfaceFlinger是 Android 系统中的一个关键服务,主要负责将不同应用程序的 2D、3D surface 进行组合,并将最终合成的图像发送到显示设备进行显示。

安卓View层次结构

Activity包含PhoneWindow、DecorView、ViewRootImpl等
在这里插入图片描述

Activity

Activity属于安卓应用程序的四大组件之一,它为用户提供了一个可视化的界面,让用户能够与应用进行交互。每一个Activity都代表着一个屏幕画面,像是登录界面、主界面等。
在安卓中,Activity是由ActivityManagerService(AMS,活动管理器服务) 创建的 。
以下是Activity的一个简单示例:

import android.app.Activity;
import android.os.Bundle;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}
}

PhoneWindow

PhoneWindow是Window类的具体实现,Window类在安卓系统里代表着一个顶级的视觉容器,它负责管理窗口的样式、背景以及标题栏等。PhoneWindow主要处理窗口的具体显示逻辑,例如设置窗口的背景、标题栏、内容视图等。

Activity与PhoneWindow两者之间的关系

  • 包含关系:Activity包含一个PhoneWindow对象,在Activity的创建过程中,会默认创建一个PhoneWindow对象。
  • 视图关联:Activity通过PhoneWindow来设置和管理其视图。Activity的setContentView()方法实际上是调用了PhoneWindow的setContentView()方法。
// Activity类中的setContentView方法
@Override
public void setContentView(@LayoutRes int layoutResID) {getWindow().setContentView(layoutResID);initWindowDecorActionBar();
}

Activity是用户交互的界面载体,负责处理用户的操作和业务逻辑;PhoneWindow则是窗口的具体实现,负责窗口的显示和管理。它们紧密协作,共同构成了安卓应用程序的用户界面。

ViewRootImpl

  • 概述:ViewRootImpl是View与WindowManager之间的桥梁,它不是一个真正的View,但它管理着一个View树的根节点,在Android系统中,每个Window都对应着一个ViewRootImpl实例。
    作用
  • 视图绘制管理:负责协调View树的绘制过程,包括测量(measure)、布局(layout)和绘制(draw)三个阶段。它会根据屏幕的刷新频率,通过Choreographer来触发视图的重绘,确保界面能够及时更新。
  • 事件分发:接收系统传递的输入事件,如触摸事件、按键事件等,并将这些事件分发给View树中的各个View进行处理。它是事件从系统到应用View的重要传递环节。
  • 与窗口管理器交互:与WindowManagerService(WMS)进行通信,负责处理窗口的创建、销毁、大小调整等操作。例如,当Activity启动时,ViewRootImpl会与WMS交互来创建窗口,并将DecorView添加到窗口中。

DecorView

在 Android 系统中,DecorView 是窗口(Window)的最顶层视图(顶级 ViewGroup),它作为整个窗口的根视图,包含了系统的装饰(如状态栏、导航栏)和应用程序的内容视图(如 Activity 的布局)。

DecorView 的作用

  • 窗口的根容器:每个 Activity 的窗口(PhoneWindow)都包含一个 DecorView,它是 View 层级的最顶层。
  • 管理系统 UI:DecorView 负责处理系统窗口装饰(如状态栏、ActionBar/Toolbar)和应用程序内容的协调。
  • 内容视图的父容器:开发者通过 setContentView() 设置的布局会被添加到 DecorView 的一个子 ViewGroup(通常是 FrameLayout,ID 为 android.R.id.content)中。

DecorView 的结构

DecorView是每个Activity界面的顶层视图,它是一个FrameLayout。
DecorView 通常包含以下两部分:

  • 系统装饰部分
    状态栏(Status Bar)、导航栏(Navigation Bar)等系统 UI。
    由主题(Theme)控制是否显示(如全屏模式会隐藏系统装饰)。
  • 应用内容部分
    通过 setContentView() 设置的布局会被添加到 android.R.id.content 这个子 FrameLayout 中。

总结

DecorView 是 Android 窗口系统的核心组件,作为连接系统 UI 和应用内容的桥梁。理解它的结构和功能有助于处理全屏、键盘交互、窗口属性等高级场景。实际开发中,通常只需通过 setContentView() 操作内容部分,而无需直接操作 DecorView。

Activity创建流程

Activity中AMS创建的。
在这里插入图片描述

  • window的初始化是在 Acticity 创建的时候初始化, 在Acticity对象创建后,会调用attach方法,Windows对象就是这个时候创建的。
  • Activity的setContentView其实调用的是PhoneWindow的setContentView。
  • setContentView中调用installDecor()进行DecorView的初始化。
  • onResume中会调用WindowMangerImpl的addView, ViewRootImpl就是在这个addView中创建的。
  • addView会调用ViewRootImpl的setView,setView调用WMS的addView并调用requestLayout。
  • requestLayout调用scheduleTraversals(会创建surface),scheduleTraversals调用见下段invalidate流程后段会有讲到主要是调用measure,layout,draw。

如下图为addView流程
在这里插入图片描述

View invalidate调用流程

在这里插入图片描述

  1. 起始调用
    当我们希望重绘某个View时,直接调用其invalidate方法 。比如在自定义View的事件处理方法(如onClick) 或者数据更新逻辑中调用。invalidate方法会转而调用invalidate(true) ,这里的参数表示是否同时使绘图缓存无效,一般全量刷新时为true。
  2. invalidateInternal方法
    invalidate(true)会调用invalidateInternal方法,此方法会进行以下操作:
    判断是否需要重绘:调用skipInvalidate方法判断该View是否不需要重绘,不需要重绘的条件是该View不可见并且未进行动画。
  • 处理重绘标志位:进一步判断View是否需要绘制,如判断表达式(mPrivateFlags & (DRAWN | HAS_BOUNDS)) == (DRAWN | HAS_BOUNDS) ,若满足重绘条件,则处理相关标志位,将当前View标记为 “脏” ,即设置mPrivateFlags中的相关标志,表明该View需要重绘。
  • 确定重绘区域:对于开启硬件加速的应用程序,调用父视图的invalidateChild函数绘制整个区域;否则只绘制指定的dirty区域(r变量所指区域)。这是一个向上回溯的过程,每一层的父View都将自己的显示区域与传入的刷新Rect做交集。
  1. ViewGroup中的调用
  • invalidateChild方法:在ViewGroup中,invalidateChild方法会从当前的布局View向上不断遍历其父布局。它会先处理子View重绘相关逻辑,比如根据子View情况设置一些标志位,然后调用父布局的invalidateChildInParent方法。
  • invalidateChildInParent方法:该方法会计算需要重绘的区域 ,涉及到location数组(表示自身左边、上边距离父组件的距离,确立在坐标系的相对位置 )和dirty矩形(包含自身宽高,确立需要重绘的面积大小 )。计算后会继续向上请求父布局重绘,直到父布局为ViewRootImpl 。
  1. ViewRootImpl中的处理
  • invalidateChildInParent方法:ViewRootImpl中的invalidateChildInParent方法会检查线程是否正确 ,若dirty为null,表示要重绘整个区域,直接调用invalidate;若dirty为空且没有动画,就不需要重绘,直接返回。否则会对重绘区域进行进一步处理,如根据滚动偏移等情况调整区域。
  • invalidate方法:调用invalidate方法后,会通过scheduleTraversals方法安排一次视图遍历。
  1. 视图遍历与绘制
  • scheduleTraversals方法:安排视图遍历工作,将任务添加到消息队列,待合适时机(比如下一次绘制周期 )执行。
  • performTraversals方法:视图遍历的核心方法,依次执行测量(performMeasure ,调用measure ,最终到onMeasure )、布局(performLayout ,调用layout ,最终到onLayout )、绘制(performDraw ,调用draw ,最终到onDraw )等步骤 ,完成整个View树的更新绘制 。其中performDraw会进一步调用drawSoftware ,最终触发View的draw方法,开始实际绘制。
    在这里插入图片描述
    Android Framework学习一:系统框架、启动过程
    Android Framework学习二:Activity创建及View绘制流程
    作者:帅得不敢出门

相关文章:

  • MyBatis 参数处理全解析
  • 北极花生物调查:在探索自然的旅程中,让每一次观察都更具意义
  • Linux工作台文件操作命令全流程解析
  • 基于Springboot+Vue3.0的前后端分离的个人旅游足迹可视化平台
  • 如何打造液态金属终結者 T-1000:多代理系统的未来构想
  • 【凑修电脑的小记录】vscode打不开
  • Mybatis中的一级二级缓存扫盲
  • 一个读写excel的简单程序(golang)
  • IP 互联网协议
  • 数字智慧方案5867丨智慧建造(BIM技术智慧工地)在施工阶段的实践与应用方案(90页PPT)(文末有下载方式)
  • GoFrame框架深度解析:grpool的优势、最佳实践与踩坑经验
  • html:table表格
  • 十分钟用Docker搭建功能齐全的Poste.io邮件服务器
  • 全感官交互革命:当 AI 大模型学会 “看、听、说、创”
  • lib和dll介绍和VS2019生成实例
  • 大模型的第一天学习-LM studio的安装和本地大模型搭建
  • IntelliJ IDEA 使用教程
  • Python Cookbook-6.16 用 Borg 惯用法来避免“单例”模式
  • 系统思考与第一性原理
  • XCTF-pwn(二)
  • 马上评|启动最高层级医政调查,维护医学一方净土
  • 解放日报:“北斗七星”列阵,AI群星闪耀
  • 体坛联播|欧冠巴萨3比3战平国米,柯洁未进入国家集训队
  • 擦亮“世界美食之都”金字招牌,淮安的努力不止于餐桌
  • 澎湃回声丨23岁小伙“被精神病”8年续:今日将被移出“重精”管理系统
  • 孙磊已任中国常驻联合国副代表、特命全权大使