zoukankan      html  css  js  c++  java
  • Android 布局渲染流程与卡顿优化

    文章内容概要

    一、手机界面UI渲染显示流程

    二、16ms原则

    三、造成卡顿的原因

    四、过度绘制介绍、检测工具、如何避免造成过度绘制造成的卡顿

    一.手机界面UI渲染显示流程

    大家都知道CPU(中央处理器)主要负责数学和逻辑运算,在很早前,CPU还负责图像的显示操作,但是这样会大大的降低CPU的运算性能,所以GPU应运而生,GPU主要负责图像的渲染与显示,至此,CPU只需要给GPU发出指令,GPU再将我们写好的页面栅格化渲染显示出来,以一个button为例!

    <Button>属性设置【Width = “100dp”;Height = “100dp”】-->通过LayoutInflater将xml映射成对象加载到内存-->检测<Button>包含的属性信息-->CPU经过计算-->将<Button>处理为多维向量图形→CPU将图形交给GPU→GPU进行图形绘制(栅格化:将图片等矢量资源,转化为一格格像素点的像素图,显示到屏幕上)(哪个位置是什么颜色的像素点,最终将图形铺满。注:手机屏幕由无数个像素点堆积而成)。

    总结来说就是CPU将UI对象计算成成多维图形(多边形、纹理),再通过OPENGL进行处理,处理完之后再交给GPU进行栅格化渲染并交给显示器进行显示。

    二.16ms原则

    由于人眼的特殊构造,对于60fps以下的帧率画面,会给人一种卡顿的现象,所以就出现了16ms原则(1000ms/60fps = 16ms),即要保证页面16ms刷新一次。

    Android系统每隔16ms发出vsync信号,触发对UI进行渲染,1s内大约刷新屏幕60次,显示60帧的数据。

    fps:画面每秒钟传输的帧率,帧率越高,画面越流程,反之越卡顿

     三.造成卡顿的原因

    上面我们讲到了16ms原则,那么16ms原则对我们的UI产生了什么样的影响呢?

    因为16ms原则,我们显示器将页面显示出来分两种情况:

    1.上述步骤在16ms内完成,true→显示器直接显示。

    2.上述步骤在16ms内没有完成(可能由于CPU计算的时间过长或者由于GPU的渲染时间过长,最终导致整个流程下来超过了16ms),false-->垂直同步等待下一帧完成。

    解释一下垂直同步机制:比如说第一帧在16ms内渲染完成,并且显示出来了,第二帧在上述的处理流程中超过了16ms,在16ms内没有完成,那么,屏幕就不会显示第二帧的数据,依旧只显示第一帧的数据,接下来处理第三帧,第三帧的数据在16ms内处理完了上述的流程,那么结果就是屏幕会将第二帧的数据和第三帧的数据一起显示出来(如果在某一处出现了丢帧的情况,大概率会影响到后面的绘制也会出现丢帧的情况),如果计算器cpu的计算能力和gpu的渲染能力很差,就会出现我们说的UI卡顿的现象。(用LOL举一个例子,比如我们1-10帧都没有在16ms内完成(打团中,UI过于复杂),第11帧在16ms内完成(打完团,回家泡泉水),这时候就会把1-11帧的数据都显示出来,这时候给人的感觉就是花里胡哨的闪现出一堆技能)

    看了上面的解释,是不是有一种明朗的感觉了,总的来说就是帧率过低,垂直同步机制的限制下,我们前面几帧的画面渲染不出来,直到某一帧我们的帧率正常了,这时候就会把前面的几帧一起渲染出来,这样就造成了我们所说的视觉上卡顿的现象了。

    四.过度绘制介绍、检测工具、如何避免造成过度绘制造成的卡顿

    既然我们知道了造成卡顿的原因了,那么,我们应该去如何检测和避免呢?这里就要介绍一下过度绘制了!

    1.什么是过度绘制

    前面我们说到了手机屏幕是由无数个像素点堆积而成的,一个像素点被我们重复多次的渲染,就是过度绘制

    2.过度绘制检测工具

    开发者选项-->调试gpu过度绘制-->显示过度绘制区域

    原色没有被过度绘制 – 这部分的像素点只在屏幕上绘制了一次。
    蓝色1次过度绘制– 这部分的像素点只在屏幕上绘制了两次。
    绿色2次过度绘制 – 这部分的像素点只在屏幕上绘制了三次。
    粉色3次过度绘制 – 这部分的像素点只在屏幕上绘制了四次。
    红色4次过度绘制 – 这部分的像素点只在屏幕上绘制了五次。
    我们的目标是尽量减少红色,看到更多的蓝色!!!
    以轻易贷为例:
    3.如何避免过度绘制

    1)避免UI层级嵌套的过深

    2)减少不必要的背景设置(根节点背景是否可以不要、系统主题背景是否可以不要等等)

    3)使用merge标签减少布局嵌套层次

    4)使用ConstraintLayout替代常见嵌套布局,减少布局层次

    5)在自定义view的时候,使用Canvas的clipRect和clipPath方法限制View的绘制区域(覆盖区域不需要绘制)

  • 相关阅读:
    hadoopfs: 未找到命令...
    WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
    centos 7 安装音乐播放器(亲测可用)(转载)
    Linux 脚本编写基础
    Zip加密
    Qt嵌入cef3关闭窗口时崩溃的问题
    C++11多线程基础
    C++11多线程(std::atomic)
    C++11多线程(thread_local)
    VS 新建RelWithDebInfo模式
  • 原文地址:https://www.cnblogs.com/upwgh/p/10897576.html
Copyright © 2011-2022 走看看