Android View的绘制流程

1.不管是View的添加,还是调用View的刷新方法invalidate()或者requestLayout(),绘制都是从ViewRootImpl的scheduleTraversals()方法开始

void scheduleTraversals() {if (!mTraversalScheduled) {mTraversalScheduled = true;mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);......}}

首先会发送一个同步屏障消息,以便及时响应UI刷新的异步消息。
然后向Choreographer注册了一个Vsync信号的监听。
2.Vsync信号通过Choreographer回调之后,会执行TraversalRunnable里面的doTraversal()方法

void doTraversal() {if (mTraversalScheduled) {mTraversalScheduled = false;mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier);performTraversals();}}

doTraversal()方法里首先会移除同步屏障消息,然后执行performTraversals()方法。

performTraversals(){performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);performLayout(lp, mWidth, mHeight);performDraw(mActiveSurfaceSyncGroup)
}

performTraversals()方法里面就会执行我们熟悉的测量、布局、绘制的方法。

3.当测量和布局执行完成后,会执行performDraw()方法,这里分为了开启硬件加速和不开启硬件加速两种绘制方式。

private boolean performDraw(@Nullable SurfaceSyncGroup surfaceSyncGroup) {draw(fullRedrawNeeded, surfaceSyncGroup, mSyncBuffer);
}
private boolean draw(boolean fullRedrawNeeded, @Nullable SurfaceSyncGroup activeSyncGroup,boolean syncBuffer) {if (isHardwareEnabled()) { //如果开启了硬件加速,使用单独的渲染线程mAttachInfo.mThreadedRenderer.draw(mView, mAttachInfo, this);} else { //使用CPU调用libSkia库渲染drawSoftware(surface, mAttachInfo,xOffset,yOffset,scalingRequired, dirty, surfaceInsets)}}

4.开启硬件加速的绘制方式
开启硬件加速,会创建一个RenderThread线程,MainThread会把需要绘制的内容记录到DisplayList里面,并通知RenderThread线程开始渲染,而此时MainThread可以从这个绘制任务中解脱出来。

void draw(View view, AttachInfo attachInfo, DrawCallbacks callbacks) {updateRootDisplayList(view, callbacks); //同步View内容到DisplayList......syncAndDrawFrame(frameInfo); // 通知渲染线程开始工作
}

RenderThread会调用libhwui库去做渲染,使用GPU的硬件资源。
不管是否开启硬件加速,只要是绘制,都会先申请空的图形缓冲(dequenebuffer),然后做内容渲染,然后再把有内容的图形缓冲加入消费队列(quenebuffer)。

5.使用软件方式绘制
软件方式绘制渲染,首先通过调用Surface的lockCanvas方法,申请图形缓冲,并关联到Skia图形库;然后调用view的draw方法绘制,这里会调用到View的ondraw()回调方法;绘制完后,通过unlockCanvasAndPost方法把绘制好的缓冲加入到图形缓冲队列,SurfaceFlinger会消费图形缓冲并合成缓冲帧,通过HWC给到屏幕驱动显示。

private boolean drawSoftware(Surface surface, AttachInfo attachInfo, int xoff, int yoff,boolean scalingRequired, Rect dirty, Rect surfaceInsets) {canvas = mSurface.lockCanvas(dirty);       mView.draw(canvas);surface.unlockCanvasAndPost(canvas);
}

大概的流程图如下:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/47629.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux中nohup(no hang up)不挂起,用于在系统后台不挂断地运行命令,即使退出终端也不会影响程序的运行。

nohup的英文全称是 no hang up,即“不挂起”。这个命令在Linux或Unix系统中非常有用,主要用于在系统后台不挂断地运行命令,即使退出终端也不会影响程序的运行。默认情况下(非重定向时),nohup会将输出写入一…

C++之类与对象(1)

目录 前言 1.类的定义 1.1类定义的格式 1.2访问限定符 1.3类域 1.3.1类定义一个作用域 1.3.2类成员在类的作用域中 1.3.3在类体外定义成员 2.实例化 2.1实例化概念 2.2对象大小 3.this指针 4.选择题补充练习 结束语 前言 Hello,友友们,好久…

Linux安装mysql(超详细版)

步骤1:新建一个文件夹,专放从网络下载的文件 [rootiZ2zeh6vyxsq620zifz8jaZ home]#mkdir soft #在根目录下创建也可以 步骤2:切换目录,进入soft文件中 [rootiZ2zeh6vyxsq620zifz8jaZ /]# cd home/ #若第一步文件建在根目…

牛客周赛 Round 51

目录 A.小红的同余 B.小红的三倍数 C.小红充电 D.小红的gcd E.小红走矩阵 F.小红的数组 这次周赛题目比较简单,算法题也基本上是板子题,出得很好(~ ̄▽ ̄)~ A.小红的同余 思路:签到题&am…

Android Studio 不再支持windows 7

Android Studio 一打开就报错: 无法找到入口 无法定位程序输入点 CreateAppContainerProfle 于动态链接库USERENV.dII 上。 截图如下: 经调查,是因为系统版本不兼容。 我目前的电脑环境:windows 7,但是现在的Android Studio要…

24年Hvv准备,6大方向,33篇技战法

进去不少小伙伴后台留言说需要技战法,因此小编对市面上的技战法进行了收集和总结,并对收集来的技战法进行了分类,总共分了6大类,共计33篇: 有需要的小伙伴关注我,点击在看,并私信回复“技战法”…

基于Java的原创歌曲分享平台

你好呀,我是计算机学姐码农小野!如果有相关需求,可以私信联系我。 开发语言:Java 数据库:MySQL 技术:SpringBootMyEclipse 工具:MyEclipse、B/S架构 系统展示 首页 用户注册界面 音乐分享…

【python】OpenCV—Coordinates Sorted Clockwise

文章目录 1、需求介绍2、算法实现3、完整代码 1、需求介绍 调用 opencv 库,绘制轮廓的矩形边框,坐标顺序为右下→左下→左上→右上,我们实现一下转化为熟悉的 左上→右上→右下→左下 形式 按照这样的顺序组织边界框坐标是执行透视转换或匹…

21天学通C++:第十三、十四章节

第十三章:类型转换运算符 类型转换是一种机制,让程序员能够暂时或永久性改变编译器对对象的解释。注意,这并不意味着程序员改变了对象本身,而只是改变了对对象的解释。可改变对象解释方式的运算符称为类型转换运算符。 为何需要…

数据库端口LookUp功能:从数据库中获取并添加数据到XML

本文将为大家介绍如何使用知行之桥EDI系统数据库端口的Lookup功能,从数据库中获取数据,并添加进输入的XML中。 使用场景:期待以输入xml中的值为判断条件从数据库中获取数据,并添加进输入xml中。 例如:接收到包含采购…

简述乐观锁和悲观锁——Java

悲观锁和乐观锁 悲观就是任何事都认为会往坏处发生,乐观就是认为任何事都会往好处发生。 打个比方,假如一个公司里只有一台打印机,如果多个人同时打印文件,可能出现混乱的问题,他的资料打印在了我的资料上&#xff0…

Yolov8网络结构学习

详解YOLOv8网络结构/环境搭建/数据集获取/训练/推理/验证/导出/部署 深入解析YOLOv8:网络结构与推理过程 YOLO? You Know! --YOLOV8详解 一:yolov8总体结构 1.Backbone:它采用了一系列卷积和 反卷积层只来提取特征,同时也使用了残差连接和…

网站开发:使用VScode安装yarn包和运行前端项目

一、首先打开PowerShell-管理员身份运行ISE 输入命令: set-ExecutionPolicy RemoteSigned 选择“全是”,表示允许在本地计算机上运行由本地用户创建的脚本,没有报错就行了 二、接着打开VScode集成终端 输入 npm install -g yarn 再次输入以…

小程序-3(页面导航+页面事件+生命周期+WXS)

目录 1.页面导航 声明式导航 导航到tabBar页面 导航到非tabBar页面 后退导航 编程式导航 后退导航 导航传参 声明式导航传参 编程式导航传参 在onload中接收导航参数 2.页面事件 下拉刷新 停止下拉刷新的效果 ​编辑 上拉触底 配置上拉触底距离 上拉触底的节…

js补环境系列之剖析:原型、原型对象、实例对象三者互相转化(不讲废话、全是干货)

【作者主页】:小鱼神1024 【擅长领域】:JS逆向、小程序逆向、AST还原、验证码突防、Python开发、浏览器插件开发、React前端开发、NestJS后端开发等等 思考下:js补环境中,什么场景会用到原型、原型对象、实例对象? 举…

谈谈大数据采集和常见问题

01 什么是数据采集 数据采集是大数据的基石,不论是现在的互联网公司,物联网公司或者传统的IT公司,每个业务流程环节都会产生大量的数据,同时用户操作的日志也会产生大量的数据,为了将这些结构化和非结构化的数据进行…

docker网络互联

最近学习docker的时候发现多了很多网卡,这些似乎都和docker有关,所以我便往下深入了解了一番; 一、docker网卡 docker 0是安装 docker 的时候生成的虚拟网桥,它在内核层连通了其他物理或者虚拟网卡,这就可以将所…

常用优秀内网穿透工具(实测详细版)

文章目录 1、前言2、安装Nginx3、配置Nginx4、启动Nginx服务4.1、配置登录页面 5、内网穿透5.1、cpolar5.1.1、cpolar软件安装5.1.2、cpolar穿透 5.2、Ngrok5.2.1、Ngrok安装5.2.2、随机域名5.2.3、固定域名5.2.4、前后端服务端口 5.3、NatApp5.4、Frp5.4.1、下载Frp5.4.2、暴露…

【数据结构】--- 栈和队列

前言 前面学习了数据结构的顺序表、单链表、双向循环链表这些结构;现在就来学习栈和队列,这里可以简单的说栈和队列是具有特殊化的线性表 一、栈 1.1、栈的概念和结构 栈是一种遵循先入后出逻辑的线性数据结构。 栈是一种特殊的线性表,它只允…

vivado FFT IP Core

文章目录 前言FFT IP 接口介绍接口简介tdata 格式说明 其他细节关于计算精度及缩放系数计算溢出架构选择数据顺序实时/非实时模式数据输入输出时序关于配置信息的应用时间节点 FFT IP 例化介绍控制代码实现 & 测试参考文献 前言 由于计算资源受限,准备将上位机 …