目录
3.硬件加速(android 3.0 中加入,android 4.0默认开启)
1.RelativeLayout与LinearLayout,GridLayout,ConstraintLayout
一.绘制原理
view绘制过程3个步骤,分别是measure、layout、draw,他们主要运行在应用框架层。而真正将数据渲染到屏幕上的则是系统的Native层的SurfaceFlinger服务来完成的。
1.屏幕撕裂
①.帧速率:指的是设备的GPU每秒能为整个屏幕绘制多少帧。
②.刷新率:指的是屏幕在一秒内的更新次数。大部分android设备为60Hz。
③.屏幕撕裂:当屏幕在刷新过程中,相邻的不同两帧图像被绘制到同一个屏幕上,造成屏幕出现明显的断裂现象。
④.屏幕撕裂出现的原因:帧速率与刷新率不同步。
⑤.解决方案:采用双缓冲区
2.垂直同步
①.双缓冲区:
所有的绘制操作放在后台缓冲区。
当操作完成将整个后台缓冲区复制到另一块,被称为前台缓冲区。
②.垂直同步:将后台缓冲区复制到前台缓冲区的过程。
③.在帧速率低于刷新率的时候双缓冲区的结果:不会出现屏幕撕裂,但是会出现第二次刷新用的还是第一帧,呈现出来的结果是造成延迟和卡顿。
3.硬件加速(android 3.0 中加入,android 4.0默认开启)
硬件加速主要是在重绘的过程中添加了一步保存操作,可以让那些不需要更新的view直接通过上次被存储下来的绘图更新。
在属性动画中记得开启硬件层,在动画结束后记得关闭硬件层,在android 6.0自动应用硬件层。
二.视图相关的工具使用
1.Profile GPU Rendering
用途:是android 4.1系统提供的开发辅助功能,该工具向用户展示帧渲染耗费的时间。
用法:在设置开发者选项的GPU显示模式模式中打开,柱形图中横轴是时间,纵轴是帧渲染耗时,有一条横线是代表16毫秒的阈值,尽量不要让纵轴超过这条横线,各个柱形图颜色有不同含义。
2.Systrace
①.是android 4.1新增的性能采样和分析的工具。
②.使用方式:
(1)在DDMS中使用
(2)用命令行使用
(3)在代码中使用
③.打开方式:用chrome打开分析
(1)Alert区域:会标记出有问题的点
(2)CPU区域:表示CPU执行时间及执行内容
(3)应用区域:给出应用中的Frames分析,表示Frame渲染是否流畅
3.Hierarchy Viewer
是android SDK自带的可视化的调试工具,用来检查布局嵌套和绘制时间,需要注意出于安全考虑,只能连接android 开发版和手机模拟器。如果想调试android真机可以用Component Tree工具和这个类似。
4.Android Lint
是ADT 16中的工具,它是代码扫描工具,通过代码静态检查来发现代码中的潜在问题。
5.调试GPU过度绘制
①.过度绘制:指的是在屏幕上某个像素点在同一帧的时间被绘制多次,从而造成GPU和CPU的资源浪费。
②.调试过程:在开发者选项中的调试GPU过度绘制中打开
③.产生原因:
(1)在xml布局中,控件有重叠且都有背景。
(2)在View的OnDraw在同一区域绘制多次。
三.布局优化
1.RelativeLayout与LinearLayout,GridLayout,ConstraintLayout
根据实际情况合理使用RelativeLayout和LinearLayout,如果相同嵌套层级可以选择LinearLayout,因为RelativeLayout性能稍低一点。如果RelativeLayout嵌套层数比LinearLayout少,则选择RelativeLayout;还有如果横轴排列可以选择网格布局GridLayout;以及复杂布局减少嵌套层次可以选择Android Studio 2.2中的约束布局ConstraintLayout。
2.复用布局include
此标签可以让布局复用,不需要相同的布局在多处复制粘贴。
3.去除冗余marge
介绍:marge并不是一个ViewGroup,也不是一个View,它相当于声明一些视图。
用法:marge可以去除布局层次嵌套,一般和include配合使用。
注意:①.marge布局中的内容排布和放在哪个布局中有关。
②.只能用于布局文件的根中使用。
③.如果需要单独加载marge标签的布局文件需要指定一个父容器(父布局)。
4.延迟加载ViewStub
定义:ViewStub中的布局文件可以延迟加载。
原理:ViewStub是一个不会绘制并且宽高为0的view,然后经过visible或者inflate则变成真正的view,原先的ViewStub将被移除。过程不可逆。
注意:①.一旦ViewStub变成visible或者inflate,它将不再可用。
②.他不能嵌套marge标签。(原理是viewStub调用LayoutInflater的inflate方法过程中进行参数传递的attachToRoot为false,导致marge不能加载)
关于attachToRoot介绍:
如果root为null,无论attachToRoot为true或者false,效果都是一样的
如果root不为null,attachToRoot为true,表示将layout布局添加到root布局中
如果root不为null,attachToRoot为false,表示不将layout布局添加到root布局,若要添加则需要手动addView
viewStub是第四种情况,是先调用inflate然后调用removeView移除原先的viewStub最后调用addView添加当前需要替换的View
5.adapterView优化
主要是convertView复用和ViewHolder的布局管理,详细见:
ListView adapter中的getView复用步骤_gongjdde的博客-CSDN博客
6.自定义视图和布局优化
①.尽量减少View的重绘操作
②.不要绘制一些用户看不见的像素,就是之前说的不要过度绘制。
③.绘制期间不要做一些非必要的操作,导致内存消耗。
7.过度绘制优化
①.移除不需要的background。子布局和父布局不要重复设置一样的background,theme和最外层的ViewGroup不要重复设置。
②.在自定义view中OnDraw方法,用canvas.clipRect来指定绘制区域,防止重叠组件发生过度绘制。