深圳网站公司建设方案/百度关键词推广公司
ViewRootImpl 在 Activity、window 和 View 三者关系之间起着承上启下的作用。一方面,ViewRootImpl 中通过 Binder 通信机制,远程调用 WindowSession 将 View 添加到 Window 中;另一方面,ViewRootImpl 在添加 View 之前,需要调用 requestLayout 方法,执行完整的 View 树的渲染操作。
ViewRootImpl 执行 View 的渲染
屏幕绘制
ViewRootImpl requestLayout 流程。requestLayout 第一个次被调用是在 setView() 方法中。
从名字也能看出,这个方法的主要目的就是请求布局操作。其中包括 View 的测量、布局和绘制等。具体代码如下
注释1处,检测是否为合法线程。一般情况下,就是检测是否为主线程;注释2处,将请求布局标识符设置为 true。这个参数决定了后续是否执行 measure 和 layout 操作。最后执行 scheduleTraversals() 方法,如下
注释1处向主线程消息队列中插入 SyncBarrierMessage。该方法发送了一个没有 target 的 Message 到 queue 中。在 next 方法获取消息时,如果发现没有 target 的 message,则在一定的时间内跳过同步消息,优先执行异步消息。这里通过调用次方法,保证 UI 绘制操作优先执行。注释2处,调用 postCallback 方法。实际上也是发送一个 Message 到主线程消息队列。
postCallback 的执行流程如下
可以看出,最终通过 Handler 发送 MessageQueue 中的 message ,被设置为异步类型的消息。
mTraversalRunable 是一个实现 Runable 接口的 TraversalRunable 对象,其 run 方法如下
可以看出,在 run() 方法中,调用了 doTraversal() 方法,并最终调用了 performTraversals() 方法。 这个方法就是真正的开始 View 的绘制流程:measure-->layout-->draw。核心代码如下
这是个比较重的方法,只负责做3件事情,即在自定义 view 中常用到的 3 个主要过程:measue、layout、draw。 下面以测量 performMeasure 实现举例。
ViewRootImpl 的 measureHierarchy
View 的测量是一层递归调用,递归执行子 View 的测量工作之后,最后决定父视图的宽和高。但是,这个递归的起源是在哪里呢?
答案就是 DecorView。因为在 measureHierarchy 方法中,最终是调用 performMeasure 方法来进行测量工作的。performMeasure 方法的实现,如下代码所示
在这个方法中,通过 getRootMeasureSpec() 方法获取了根 View 的 MeasureSpec() 方法。实际上 MeasureSpec 的宽高此处获取的值是 Window 的宽高。
ViewRootImpl 的 performMeasure
这个方法很简单,只是执行了 mView 的 measure 方法。这个 mView 就是 DecorView。其 DecorView 的 measure 方法中会调用 onMeasure 方法,而 DecorView 是继承 FramLayout 的。因此,最终会执行 FramLayout 的 onMeasure 方法,并递归调用子 View 的 onMeasure 方法。
performLayout() 也是类似的过程,这里不再分析。
ViewRootImpl 的 performDraw
从图中可以看出,在 performDraw 方法中调用的 ViewRootImpl 的 draw 方法。在 draw 方法中进行 UI 绘制操作,Android 系统提供了两种绘制方式。图中1处标识 App 开启了硬件加速功能,所以会启动硬件加速绘制;图中2处表示使用软件绘制,
软件和硬件绘制
ViewRootImpl 中有一个非常重要的对象 Suface,之所以说 ViewRootImpl 的一个核心功能是负责 UI 渲染。原因就在于,在 ViewRootImpl 中会将在 draw 方法中绘制的 UI 元素,绑定到这个 Surface 上。如果说 canvas 是画板,那么 surface 就是画板上的画纸。Surface 中的内容最终会被传递给底层的 SurfaceFlinger,最终将 Surface 中的内容进行合成并显示在屏幕上。
软件绘制 drawSoftware
图中1处,就是调用 DecorView 的 draw 方法。将 UI 元素绘制到画布 canvas 对象中;图中2处,请求将 canvas 中的内容显示到屏幕上。实际上就是将 canvas 中的内容提交给 SurfaceFlinger 进行合成处理。默认情况下,软件绘制没有采用 GPU 渲染的方式,drawSoftware 工作完全由 CPU 来完成。
DecorView 并没有复写 draw 方法,因此,实际上是调用顶层 View 的 draw 方法,如下代码
图中1处绘制 view 的背景;图中2处绘制 view 的自身内容;图中3处表示对 draw 事件进行分发,在 view 中是空实现,实际调用的是 viewGroup 中的实现,并递归调用子 View 的 draw 事件。
启用硬件加速
可以在 ViewRootImpl 的 draw 方法中,通过如下方法判断是否启用硬件加速
我们可以在 AndroidManifest.xml 清单文件中,指定 Application 或者某一个 Activity 支持硬件加速
此外,还可以进行粒度更小的硬件加速设置,比如设置某个 View 支持硬件加速
之所以会有这么多级的支持区分,主要是因为并不是所有的 2D 绘制操作都支持硬件加速。
硬件加速优势
硬件加速能够提高 UI 渲染的性能。在 ViewRootImpl 的 draw 方法中,mThreadedRenderer 是 ThreadedRenderer 类型
其 darw 方法具体如下
图中1处就是硬件加速的特殊之处,通过 updateRootDisplayList() 方法,将 View 视图抽象成一个 RendererLoad 对象,并构建 View 的 drawOp 树;图中2处通知 renderThread 进行绘制操作。
renderThread 是一个单例线程,每个进程最多只有一个硬件渲染线程,这样就不会存在多线程并发访问冲突问题。updateRootDisplayList() 具体如下
Android 硬件加速过程中,View 视图被抽象成 RenderNode 节点。View 中的绘制操作都会被抽象成一个个 DrawOp。比如,View 中 drawLine,构建过程中就会被抽象成一个 DrawLineOp。drawBitmap 操作会被抽象成 DrawBitmapOp,每个子 View 的绘制被抽象成 DrawRenderNodeOp,每个 DrawOp 有对应的 OpenGL 绘制命令。
上图中1处遍历 view 递归构建 DrawOp;2处根据 canvas 将所有的 operation 进行缓存操作。所有的 DrawOp 对应 OpenGL 命令构建完成后,就需要使用 RenderProxy 向 RenderThread 发送消息。请求 OpenGL 线程进行渲染。整个渲染过程是通过 GPU 并在不同线程绘制渲染图像。因此整个流程会更加流程。
View 的两种刷新方式
Invalidate 轻量级刷新
通过 invalidate 来刷新 View,与 requestLayout 的区别在于它不一定会触发 View 的 measure 和 layout 的操作,多数情况下只会执行 draw 操作。在 View 的 measure 方法中,有如下几行代码
可以看出,如果要触发 onMeasure 方法,需要对 View 设置 PFLAG_FORCE_LAYOUT 的标志位。而这个标志位在 requestLayout 方法中被设置。 invalidate 并没有设置此标志位。
再看一下 onLayout 方法
可以看出当 view 的位置发生改变或者添加 PFLAG_FORCE_LAYOUT 标志位,onLayout 才会被执行。
当调用 invalidate 方法时,如果 View 的位置并没有发生改变,则 View 不会触发重新布局的操作。
postInvalidate
postInvalidate 在面试中经常被问道,实际开发中使用频率也是较高的。invalidate 与 postInvalidate 两者之间的区别是 invalidate 是在 UI 线程调用,postInvalidate 是在非 UI 线程调用。postInvalidate 实现如下
最终还是在 ViewRootImpl 中进行操作。
ViewRootImpl 的 dispatchInvalidateDelayed 在 非 UI 线程中,通过 Handler 发送了一个延时 Message。
因为 Handler 是在主线程中创建的,所以 handleMessage 最终会在主线程中被执行。方法如下
上图中的 msg.obj 就是发生 postInvalidate 的 view 对象。可以看出,最终还是回到了 UI 线程,执行了 View 的 invalidate 方法。
个人理解,做过 android 开发的都知道,只有 UI 线程才可以刷新 view 控件。但是,事实却并非如此。在 ViewRootImpl 中对 view 进行刷新时,会检测当前线程的合法性,下图中 mThread 是被赋值为当前线程。而 ViewRootImpl 是在 UI 线程中被创建的,因此只有 UI 线程可以进行 view 刷新。但是,如果我们能在非 UI 线程中创建 ViewRootImpl,并通过这个 ViewRootImpl 进行 view 的添加和绘制操作,那么后续理论上也是可以在非 UI 线程中刷新 view 控件的。只是维护成本较高,很少有人去做这件事情。
总结
主要介绍了 ViewRootImpl 是如何执行 View 的渲染操作的。其中核心方法在 performTraversals 方法中会按顺序执行 measure->layout->draw 操作。
介绍了软件绘制和硬件绘制的区别
介绍了 View 刷新的两种方式 Invalidate 和 postInvalidate。
相关文章:
Android---如何同view进行渲染
ViewRootImpl 在 Activity、window 和 View 三者关系之间起着承上启下的作用。一方面,ViewRootImpl 中通过 Binder 通信机制,远程调用 WindowSession 将 View 添加到 Window 中;另一方面,ViewRootImpl 在添加 View 之前࿰…...

【LeetCode:26. 删除有序数组中的重复项 | 双指针】
🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,…...

如何判断一个对象是不是一个空对象?
在JavaScript中,可以使用以下方法来判断一个对象是否为空对象: 1:使用Object.keys()方法:Object.keys()方法返回一个包含对象自身可枚举属性的数组。通过判断该数组的长度,可以确定对象是否为空对象。 function isEm…...

C/C++ “variable set but not used“的 警告问题解决方案
在编程的过程中,会有一些预留的变量暂时不用,但是编译过程编译器警告 会报错无法编译通过针对这个问题,采用下面的解决方案比较方便。 错误如下形式: 三种解决方法: 1.可以在变量前加上(void)就…...

JAVA安全入门之反射
反射 对于反射这个概念来说,直白的讲就是: 对象可以通过反射获取他的类,类可以通过反射拿到所有⽅法(包括私有),拿到的⽅法可以调⽤而众所周知 JAVA 是一门静态语言,我们通过反射就可以达到动…...

【c++|opencv】一、基础操作---2.图像信息获取
every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 图像信息获取,roi 1. 图像信息获取 // 获取图像信息#include <iostream> #include <opencv2/opencv.hpp>using namespace cv; …...

HarmonyOS开发:探索组件化模式开发
前言 组件化一直是移动端比较流行的开发方式,有着编译运行快,业务逻辑分明,任务划分清晰等优点,针对Android端的组件化,之前有比较系统的总结过相关文章,感兴趣的朋友,可以查看,点击…...

目标URL启用了不安全的HTTP方法
修复中危web项目漏洞(目标URL启用了不安全的HTTP方法) 漏洞名 :目标URL启用了不安全的HTTP方法 等级: 中危 漏洞位置: PUT DELETE 描述: Web服务器配置为允许使用危险的HTTP方法,如PUT、MOVE、…...

大数据之LibrA数据库系统告警处理(ALM-12001 审计日志转储失败)
告警解释 根据本地历史数据备份策略,集群的审计日志需要转储到第三方服务器上。如果转储服务器满足配置条件,审计日志可以成功转储。审计日志转储失败,系统产生此告警。如果第三方服务器的转储目录磁盘空间不足,或者用户修改了转…...

大模型该被知道的技术实现-面向垂直领域
一个高度清晰的思维导图截图奉上(下载:需3积分) 内容截图...

赛灵思产品系列
FPGA概述: FPGA的性能主要划分为以下几个方面: 1. 逻辑单元数量:逻辑单元数量越多,FPGA的处理能力越强。 2. 存储单元数量:存储单元数量越多,FPGA的存储能力越强。 3. 时钟频率:时钟频率越高&a…...

[Linux C] signal 的使用
前言: signal 是一种通信机制,可以跨进程发送,可以同进程跨线程发送,可以不同进程向指定线程发送。 信号的创建有两套api,一个是signal,一个是sigaction,signal缺陷很多,比如没有提…...

AI时代产品经理升级之道:ChatGPT让产品经理插上翅膀
💂 个人网站:【工具大全】【游戏大全】【神级源码资源网】🤟 前端学习课程:👉【28个案例趣学前端】【400个JS面试题】💅 寻找学习交流、摸鱼划水的小伙伴,请点击【摸鱼学习交流群】 AI时代的产品经理面临着…...

计算机网络重点概念整理-第七章 网络安全【期末复习|考研复习】
计算机网络复习系列文章传送门: 第一章 计算机网络概述 第二章 物理层 第三章 数据链路层 第四章 网络层 第五章 传输层 第六章 应用层 第七章 网络安全 计算机网络整理-简称&缩写 文章目录 前言七、网络安全7.1网络安全7.2 网络威胁7.3 加密7.3.1 对称加密7.3.…...

【LeetCode力扣】42. 接雨水
目录 1、题目介绍 2、解题思路 2.1、暴力破解法 2.2、双指针法 1、题目介绍 原题链接: 42. 接雨水 - 力扣(LeetCode) 示例 1: 输入:height [0,1,0,2,1,0,1,3,2,1,2,1]输出:6解释:上面是由…...

03、SpringCloud -- 动态倒计时 及 当前用户的获取(用户未登录提示其登录)
目录 动态倒计时需求思路代码效果优化获取当前登录用户思路代码前端后端controllerservice接口impl实现效果问题修改动态倒计时 需求 根据不同时间展示不同状态,动态显示时间,如原型图: 思...

Mac用户心目中的四款首选原型工具
Wireframe、Mockup和prototype在原型工具中有什么区别? 无论你是刚进入这个行业的UX/UI设计师,还是已经进入这个行业多年的老手,你都必须在制作原型的过程中接触或听到三个非常重要的原型术语:“wireframe(线框图)Mockup”或“pr…...

国内内卷太严重,还不考虑一下在海外接单?那这几个平台你知道吗?
作为一个程序员,在平台上接单赚点外快是再正常不过的事情了,但是现今国内各个平台都内卷比较严重,你是否考虑过去“外面的世界”看看? 如果想过,那么这几个外国的接单平台你都知道吗? 接下来就和我一起来看…...

在excel中如何打出上标、下标
例如,想把A2的2变为下标。 在单元中输入内容: 选中2: 右键单击,然后点击“设置单元格格式”: 在特殊效果的下面勾选“下标”,然后点击下面的“确定”按钮: 就将2变为下标了:…...

LoongArch 五级流水线实现
在单周期的基础上进行拆分成取指、译码、执行、访存、写回五级流水线。 mycpu_top.v include "mycpu.h"module id_stage(input clk ,input reset ,//allowininput …...

「Qt中文教程指南」如何创建基于Qt Widget的应用程序(四)
Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写,所有平台无差别运行,更提供了几乎所有开发过程中需要用到的工具。如今,Qt已被运用于超过70个行业、数千家企业,支持数百万设备及应用。 本文描述了如何使用…...

11、SpringCloud -- 利用redis优化查询秒杀商品的数据(就是可以把商品数据先存到redis中)
目录 秒杀商品数据存到redis中并查询需求hash理解代码:RedisService商品数据初始化:查询 测试: 秒杀商品数据存到redis中并查询 需求 利用redis优化查询秒杀商品的数据,就是可以把商品数据先存到redis中,要查的时候先…...

计算节点上iptables安全组分析
计算节点上iptables安全组分析 之前介绍过neutron 安全组基于iptables 和 ct 实现,分析一下计算节点上面的neutron 安全组的iptables,加深一下理解iptables以及安全组的实现。(PS: 如下基于openstack stein) 查看某计算节点上面的iptables …...

香港科技大学广州|可持续能源与环境学域博士招生宣讲会—上海专场!!!(暨全额奖学金政策)
香港科技大学广州|可持续能源与环境学域博士招生宣讲会—上海专场!!!(暨全额奖学金政策) “面向未来改变游戏规则的——可持续能源与环境学域” ���专注于能源环境跨学…...

有没有什么网站可以在线做视频脚本?批量制作视频,批量替换素材混剪?
随着视频内容的普及和需求的不断增长,越来越多的个人和团队开始涉足视频制作领域。为了提高效率并满足大量制作需求,许多在线视频制作工具应运而生,提供了一系列便捷的功能,如在线视频脚本编辑、批量制作视频、批量替换素材和混剪…...

【python数学建模】特征值与特征向量运用
1、求数列通项 (1)转化为求矩阵的幂次问题 例:求斐波那契数列的通项公式 已知斐波那契数列满足: F k 2 F k 1 F k F_{k2}F_{k1}F_{k} Fk2Fk1Fk (a) 降阶:将二阶差分方程转化为一阶…...

什么是 CNN? 卷积神经网络? 怎么用 CNN 进行分类?(1)
先看卷积是啥,url: https://www.bilibili.com/video/BV1JX4y1K7Dr/?spm_id_from333.337.search-card.all.click&vd_source7a1a0bc74158c6993c7355c5490fc600 下面这个式子就是卷积 看完了,感觉似懂非懂 下一个参考视频:https://www.y…...

java解决修改图片尺寸,压缩图片后出现背景变黑,图片字体模糊问题
将以下数学公式的图片使用Hutool提供的图片工具类改变尺寸 代码如下: package com.jason.common.file.word;import cn.hutool.core.img.ImgUtil; import cn.hutool.core.io.FileUtil;import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage;…...

jq/js检测鼠标指针移动离开页面
通过 mouseout 鼠标事件,判断鼠标去往哪个元素 知识点:relatedTarget 事件属性 定义和用法 relatedTarget 事件属性返回与事件的目标节点相关的节点。 对于 mouseover 事件来说,该属性是鼠标指针移到目标节点上时所离开的那个节点。 对于 …...

ICC2: 如何在显示GUI操作产生的命令
我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧? 拾陆楼知识星球入口 ICC2:自定义快捷键和菜单 VIEW -> Perference -> Global Settings 把display commands in logging console 下面几个都勾上即可。...