卡顿优化小结
卡顿的本质
卡顿的本质是因为一次垂直同步信号来的时候,当前帧要显示的图像数据还没准备好,只能等待16ms下一次垂直同步信号来时才能更新画面,在这段时间里显示器只能一直停留在上一帧的画面,如果跳过的帧数过多,就会看到上一帧的画面一直没有变化,给人的感觉就是卡顿;
垂直同步信号:是为了解决显示器刷新率和CPU/GPU生产图形数据速度不匹配问题;当CPU/GPU制造图形数据的速度大于显示器刷新速度时,生产的很多帧数据就浪费了,浪费了cpu/GPU的性能;而当CPU/GPU制造帧数据的速度小于显示器刷新速度时,就会导致跳帧,也就是会感觉画面更新很慢,给人卡顿的感觉;
有了垂直同步信号后,当屏幕显示完一帧画面后会发送一个垂直同步信号,cpu、gpu在接收到信号后才开始生产帧数据,这样就不会浪费cpu/GPU性能
GPU的ALU单元比CPU多很多,GPU更擅长计算;而cpu更擅长逻辑运算
卡顿优化
造成卡顿的原因主要有这三个方面:
-
第一,在主线程上做了一些耗时操作,我们需要将这些耗时操作转移到线程池中执行
-
第二,短时间内创建大量对象造成频繁GC,比如在自定义View的onDraw方法中、列表滚动事件中、创建了大量对象就会引起GC频繁;解决办法就是通过享元模式复用已经创建过的对象,避免对象大量重复创建
-
第三,布局设计不合理,导致过度绘制,层级过多,从而引起绘制需要的时间更长;解决办法是通过include、merge、viewStub、ConstraintLayout这些标签对布局进行优化,减少布局的层级,减少过度绘制的现象
卡顿监测
-
对于布局方面的检测,我们可以通过Android Studio自带的Layout Inspector查看界面中的布局情况;在开发者模式中打开过度绘制开关,可以查看应用过度绘制情况
-
通过编舞者类不断请求发起垂直同步信号请求,每次回调时计算跳过的帧数,超过一定的阈值,就认为卡顿发生了;编舞者类也会打印出跳帧的系统log
-
在一些可能比较耗时的代码前后预先插入统计耗时的代码;也可以调用Trace.beginSection和endSection代码,然后通过系统工具systemtrace分析该段代码运行情况
-
如果需要定位到具体比较耗时的代码,可以通过给主线程Looper设置一个自定义打印log类,Looper会在事件分发前后使用该Log打印类输出log;我们可以在事件分发之前开始定时收集主线程的调用栈信息,在事件分发结束后判断耗时情况,如果跳过一定的帧数,则判定卡顿发生,并且打印出这段时间内主线程的调用栈情况,从而定位到是主线程哪里耗时比较多,第三方监控卡顿框架BlockCanary就是通过这种方式实现卡顿监控的
UI渲染机制
-
当我们在Activity的onCreate方法中设置一个布局之后,会先创建一个根布局DecorView,然后通过LayoutInflater将我们设置的xml布局文件解析成View对象并添加到DecorView中
-
接着在onResume生命周期过后会回调makeVisible方法;接着依次调用WindowManagerImpl\WindowManagerGlobal的addView方法,为DecorView生成一个ViewRootImpl对象用于管理DevorView以及和WMS通信;
-
接着DecorView会调用setView方法,在里面会调用requestLayout方法请求开始绘制,并将窗体相关信息添加到WMS中
-
在requestLayout方法中不会立刻执行View的三大绘制流程方法,而是先通过消息队列发送一个同步屏障消息,然后通过编舞者类发起一次垂直同步信息请求,当垂直同步信息来的时候,ViewRootImpl就开始绘制并调用View的onMeasure\onLayout\onDraw方法,在调用绘制方法draw之前,会通过Surface创建一个画布Canvas传递到各个View的onDraw方法中,各个View就在这个画布上进行绘制图像;绘制完成之后,会将这个带有绘制数据的Surface发送给SurfaceFlinger,SurfaceFlinger将应用绘制数据和系统UI数据整合之后交给GPU进行栅格化渲染,最终形成可供显示器显示的一帧数据存到帧缓冲区,等待一次垂直同步信号后显示到屏幕
-
之后的每次View刷新,都会最终调用到ViewRootImpl的requestLayout方法,等待一次垂直同步信号后执行绘制流程
编舞者类Choreographer
编舞者类主要是用于控制绘制节奏,通过请求垂直同步信号,接收垂直同步信号来通知应用层绘制的时机,主要流程如下:
-
编舞者类在每一个线程都有一个唯一的单例对象,它是存在ThreadLocal中的
-
当调用它的postCalllback或者postFrameCallback方法时,会将回调方法保存到队列中,这两个方法的区别是postFrameCallback请求的是动画类型的垂直同步信号,而postCallback支持传入指定类型的垂直同步信号;垂直同步信号类型一共有五种:分别用于 输入、动画、插入动画、绘制、提交;不同类型只是它们的callback调用顺序不一样,input类型的callback最先调用
-
接着会判断要不要延迟发起请求、当前线程是否跟Looper线程是否一致来决定要不要立刻发起请求;发起请求是通过调用native方法实现的,主要也是通过向SurfaceFlinger注册监听垂直同步信号
-
当接收到垂直同步信号时,会调用编舞者类的回调方法,编舞者类接着会通过Handler发送异步消息去调用doFrame方法
-
在doFrame方法中会判断有没有跳帧,因为消息队列中可能会有其他耗时任务在执行,导致doFrame方法执行延后,如果跳帧了就输出log、接着就会依次调用那五种类型的Callback回调函数
-
然后就可以在接收到垂直同步信号后进行UI绘制、动画等操作
同步屏障
Handler中有三种类型的消息,同步消息、同步屏障和异步消息;Message里有个属性标记是否异步,默认是同步消息;而同步屏障消息是一个target等于null的Message对象,这个target也就是Handler;当消息队列遍历到这个同步屏障消息时,会开启一个while循环,优先遍历处理之后的异步消息;
相关文章:

卡顿优化小结
卡顿的本质 卡顿的本质是因为一次垂直同步信号来的时候,当前帧要显示的图像数据还没准备好,只能等待16ms下一次垂直同步信号来时才能更新画面,在这段时间里显示器只能一直停留在上一帧的画面,如果跳过的帧数过多,就会…...

springboot前端ajax 04 关于后台传的时间和状态在前端的转换
修改状态及时间格式 在jsp中,时间显式: 只需要把json的时间部分改为用Date对象来显示就好了。 <td>new Date(jsonObj[i].startTime).toLocaleString()</td> <td>new Date(jsonObj[i].endTime).toLocaleString()</td> 状态对象…...

解决Windows微信和 PowerToys 的键盘管理器冲突
Windows开机之后PowerToys能正常使用, 但是打开微信之后设置好的快捷键映射就全部失效了 打开微信 -> 左下角三条杠 -> 设置 -> 快捷键 首先我把微信的快捷键全部清空了,发现还是没用 然后发现了设置里默认勾选了检测快捷键,我在想程序肯定是一直在后台检测,而powerTo…...

组会时间的工作
1. 党支部活动 看看组织生活记录本写完了没有 2. 论文翻译...

linux udp bind 返回值-1分析
在linux socket通信中,我们通常用到open/bind/read/write等内部函数,那么当这些函数返回值为-1的时候,我们怎么进一步定位呢! (1)怎么打印出返回值出错的原因呢!系统调用的错误都会存放在errno中 errno需要的头文件: #include<errno.h> strerror头文件,将错误信…...

Hexo搭建博客
文章目录开始安装使用配置主题配置gitee配置域名之前配置过hexo但是后来hexo文件夹莫名其妙崩了,我也懒得修理,就没管了,现在又想重拾回来。然后hexo可以搭建静态博客网站,放在github或者gitee都行,有免费的网页空间&a…...

Lesson11:http协议
前言 应用层:就是程序员基于socket接口之上编写的具体逻辑,做了很多工作,都是和文本处理有关的--- 协议分析与处理http协议,一定会具有大量的文体分析和协议处理如果用户想再url中包含url本身用来作为特殊字符的字符,url形式的时候,浏览器会自动给我们进行编码encode一般服务端…...

计算机信息安全有哪些SCI期刊推荐? - 易智编译EaseEditing
以下是计算机信息安全方向的SCI期刊推荐: IEEE Transactions on Information Forensics and Security 该期刊主要发表信息安全和数字取证方面的原创性研究,包括数据安全、网络安全、身份认证、加密、信息隐藏等领域的研究成果。该期刊的影响因子为8.134…...

CNVD-2023-12632 泛微e-cology9 sql注入 附poc
目录 漏洞描述影响版本漏洞复现漏洞修复 漏洞描述 泛微 E-Cology9 协同办公系统是一套基于 JSP 及 SQL Server 数据库的 OA 系统,包括知识文档管理、人力资源管理、客户关系管理、项目管理、财务管理、工作流程管理、数据中心等打造协同高效的企业管理环境&#…...

赛宁网安合作伙伴大会成功举办,重磅发布SCBaaS服务!
3月29日,“赛宁网安合作伙伴大会”在江苏南京隆重举办。大会现场汇集网络安全数字化领域的专业人才、技术专家,共同研讨数字安全发展趋势,分享智能安全解决方案和技术创新产品。 会上,赛宁网安产品专家针对数字化靶场、网络安…...

R语言 4.2.2安装包下载及安装教程
[软件名称]:R语言 4.2.2 [软件大小]: 75.6 MB [安装环境]: Win11/Win10/Win7 [软件安装包下载]: https://pan.quark.cn/s/b6f604930d04 R语言软件的GUI界面比较的简陋,只有一个命令行窗口,且每次创建图片都会跳出一个新的窗口,比较的繁琐,我们可以安装RStudio,来更方便的操作R(…...

快速玩转 CNStack 2.0 流量防护
作者:冠钰 云原生下的服务治理 在云原生技术的演进过程中,依托云原生技术能力,形成一个可以向下管理基础设施,向上管理业务应用的技术中台,越来越成为企业期望的云原生技术落地趋势。随着云原生技术中台 CNStack 发布…...

你还在用原生 poi 处理 excel?太麻烦了来瞧瞧这个
1、easypoi 前言 Excel 在日常工作中经常被用来存储用例信息,是一种非常便捷的数据存储工具有着众多的优点,我们就不一一介绍了。 今天来讲讲 Java 操作 Excel,总所周知 Java 是世界上最好的语言(不容反驳)ÿ…...

No.027<软考>《(高项)备考大全》【第11章】项目风险管理
【第11章】项目风险管理1 章节相关1.1 考试相关1.2 ITO口诀2 章节概述2.1 风险的含义2.2 风险定义的三个必要条件2.3 项目风险2.4 风险的随机性和相对性2.5 风险的分类2.6 风险成本2.7.1 风险损失有形成本2.7.2 风险损失无形成本2.8 项目风险管理过程3 规划风险管理4 识别风险4…...

mit6.824 lab2c-数据持久化
目录2c简介2b、2a问题测试时间2c简介 简单的说,raft需要将currentTerm、voteFor、entries(当前的所有日志)保存到硬盘进行持久化存储。 保存的方法:在变量改变时,利用persist()中的gob将变量序列化,存储在persister结构体中。&a…...

leaflet使用L.geoJSON加载文件,参数filter的使用方法(127)
第127个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet中加载geojson文件,这里介绍filter的使用方法。filter将用于决定是否包含某个功能的函数。 默认是包括所有特征。 直接复制下面的 vue+leaflet源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方…...

23年5月高项学习笔记7—— 质量管理
质量通常指产品质量,也包括工作质量(即过程),产品质量是指产品的使用价值,工作质量是产品质量的保证,反映了产品质量直接相关的工作的对产品质量的保证程度。 公差:结果的可接受范围 项目合同…...

学编程需要哪些基础呢?一起来看看吧
众所周知程序员薪酬高、工作环境好,是很多人向往的职业,那么学编程需要什么基础?0基础能学编程吗? 学编程需要什么基础? 1、数学基础 从计算机发展和应用的历史来看计算机的数学模型和体系结构等都是有数学家提出的&…...

PECS In Java泛型类型通配符限定之<? extends T>与<? super T>
泛型类型通配符限定 🚆PECS | 类型通配符限定如何使用“<? extends T>”和“<? super T>”通配符java源码示例PECS | 类型通配符限定 PECS原则是指在使用泛型时,当我们需要传递一个泛型集合时,如何选择适当的泛型类型通配符来…...

电子招投标系统源码之了解电子招标投标全流程
随着各级政府部门的大力推进,以及国内互联网的建设,电子招投标已经逐渐成为国内主流的招标投标方式,但是依然有很多人对电子招投标的流程不够了解,在具体操作上存在困难。虽然各个交易平台的招标投标在线操作会略有不同࿰…...

admin Tips
1 获取 当前浏览器 url new URL(window.location.href)...

ToBeWritten之Radare2 使用教程
也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大 少走了弯路,也就错过了风景,无论如何,感谢经历 转移发布平台通知:将不再在CSDN博客发布新文章,敬…...

实时翻译屏幕插件
程序插件的功能是:点击按钮,将获取屏幕截图,然后翻译输出图片。(目前只支持翻译英语) 要实现这个功能,我们可以使用Python编程语言,结合一些库来完成。以下是一个简单的实现方案: …...

代码随想录算法训练营第二天| 977,209,59
977.有序数组的平方 * 数组平方后,最大值一定是在两侧 因为可以采用双指针 package algor.trainingcamp;import java.util.Arrays;/*** author lizhe* version 1.0* description: https://leetcode.cn/problems/squares-of-a-sorted-array/** 有序数组的平方* 给…...

echarts 地图板块点击着色,移除着色
//选择省份变色 showProvince(name) { this.oldName name; this.mapChart && this.mapChart.dispatchAction({ type: geoSelect, name }) }, //移除上次点击变色 hideProvince() { this.mapChart && this.mapChart.dispatchAction({ type: geoUnSelect, name:…...

Visual Studio Code (vscode)自定义用户代码段快速打出for循环等
比如fori这样的快捷键就打不出代码块了 自定义用户代码块的方法: 工具栏 > 文件 > 首选项 > 用户代码片段 然后在弹出的搜索框中填写javascript.json 有提示 不用打全就行 (会有javascript选中) 打开配置文件javascript.json 这里面显示的就是编写代码块的例子 "…...

RocketMQ客户端配置详解
文章目录 ClientConfignamesrvAddrinstanceNameclientIPclientCallbackExecutorThreadspollNameServerIntervalheartbeatBrokerIntervalpersistConsumerOffsetIntervalvipChannelEnabledDefaultMQProducerproducerGroupcreateTopicKeydefaultTopicQueueNumssendMsgTimeoutcompr…...

STM32基于STM32CubeMX DMA + EXTI读取DS1307数据
STM32基于STM32CubeMX DMA EXTI读取DS1307数据✨申明:本文章仅发表在CSDN网站,任何其他网站,未注明来源,见此内容均为盗链和爬取,请多多尊重和支持原创!🍁对于文中所提供的相关资源链接将作不定期更换。&a…...

C#中的枚举器和迭代器
目录 一、可枚举类型和枚举器 1. 枚举器 2. 可枚举类 3. 使用 IEnumerable 和 IEnumerator 案例 4. 泛型枚举接口 二、迭代器 1. 使用迭代器创建枚举器 2. 使用迭代器创建可枚举类 3. 常见的迭代器模式 4. 产生多个枚举类型 5. 将迭代器作为属性 6. 迭代器的实质 一…...

中山大学人工智能学院——考研上岸经验贴
文章目录初试个人基本情况408数学英语政治复试初试 首先是初试成绩,中山大学在2.21号就公布了成绩和排名,这点很不错,有很多学校只公布成绩而没有排名。我的初试总分386,总排名第二,各个科目还是比较平均的࿱…...