Android优化笔记(二)——渲染篇(优化)

时间:2024-04-06 22:21:21

UI过度绘制

过度绘制是指屏幕上的某个像素点在同一帧的时间内绘制了多次。

1.调试GPU过度绘制选项

检测过度绘制可以借助开发者选项里自带的调试GPU过度绘制选项。
Android优化笔记(二)——渲染篇(优化)

1.原色 – 没有被过度绘制 – 绘制了一次。
2.蓝色 – 1次过度绘制 – 绘制了两次。
3.绿色 – 2次过度绘制 – 绘制了三次。
4.粉色 – 3次过度绘制 – 绘制了四次。
5.红色 – 4次过度绘制 – 绘制了五次。

原则上大片的蓝色还是可以接受的,中等大小的绿色区域是可以接受的但你应该尝试优化、减少它们,小范围粉色可以接受,而红色则是错误的,应该修复它们。

2.Tracer for OpenGL ES

另一个检测工具是Tracer for OpenGL ES,Tracer for OpenGL ES(http://developer.android.com/tools/help/gltracer.html)是Android SDK中新增加的开发工具,可逐帧(准确得说是逐函数)记录app用OpenGL ES的绘制过程。它提供了每个OpenGL函数调用的消耗时间,所以很多时候用来作performance分析。

在DDMS里通过Tracer for OpenGL ES生成一份gltrace文件,打开该文件后,点到glDrawArrays命令(蓝色)就可以观察绘制过程,通过观察绘制过程,我们就能知道在绘制区域里发生的过度绘制现象了。

3.常见过度绘制优化

(1)去掉window的默认背景,DecorView的background此时对我们来说是无用的,但是它会产生一次Overdraw,带来绘制性能损耗。去掉window的背景可以在onCreate()中setContentView()之后调用
getWindow().setBackgroundDrawable(null);
(2)去掉不必要的背景,有时候为了方便会先给Layout设置一个整体的背景,再给子View设置背景,这里也会造成重叠。
(3)在自定义View的onDraw中,如果涉及到重叠的绘制view时,可以考虑利用局部绘制避免过度绘制。canvas.clipRect()方法,只会显示被裁剪的区域,之外的区域将不会显示。并且可以使用canvas.quickreject()来判断是否没和某个矩形相交。在自定义View中,如果有叠加的部分,可以用clipRect来裁剪要显示的区域。
(4)从设计上去优化此问题,简单易用才是好的。


布局问题

不合理的布局也会影响UI的渲染性能,例如布局的无用嵌套,布局的选择不合理等。

1.Hierarchy Viewer

Hierarchy Viewer可以很方便可视化的查看屏幕上套嵌view结构,是查看你的View结构的实用工具。这个工具包含在DDMS中。
在Window窗口页选择要查看的组件就能看到层级关系,在快捷工具栏中点击Obtain layout times for tree rooted at selected node就可以查看某个View的耗时。

2.Lint工具检查代码

Lint是Android Studio自带的代码检查工具(Ecilpse也有),通过静态检测代码的方式查看代码中存在的问题,Android Studio从菜单栏选择Analyze→Inspect Code来启用。性能相关的重点关注performance选项下的条目,几个重要的如下:
Android优化笔记(二)——渲染篇(优化)
(1)Layout has too many views:太多控件,超过80个。
(2)Layout hierarchy is too deep:层级太深,超过10层。
(3)Obsolete layout params:Layout中有无用的参数。
(4)Useless leaf layout:layout不包含子View,可以删除。
(5)Useless parent layout:View的父亲没有用,应该移除。

3.常见布局问题优化

(1)减少层级,合理使用RelativeLayout和LinearLayout。但是要注意RelativeLayout会对子View进行两次measure(LinearLayout中有weight属性时也会进行两次测量),如果布局层级不是很深要注意取舍。层级相同时使用LinearLayout,层级较深时使用RelativeLayout优化。
(2)合理使用merge标签消除层级,注意的是merge标签只能用在布局XML文件的根元素,也得为其指定一个ViewGroup。
(3)使用ViewStub来隐藏不显示的Layout,而不是设置成View.GONE。
(4)使用标签来实现布局复用。
(5)少用wrap_content,wrap_content会增加布局measure时的计算成本,已知宽高固定时,不用wrap_content。


代码优化

代码优化主要是在逻辑层,找出一些主线程耗时较大,优化逻辑来增加界面的流畅度。

1.TraceView

TraceView是一个很好的性能分析工具,它可以分析函数的调用过程,对代码进行性能分析,图形化界面能帮助我们直观的分析问题。

使用TraceView有两种方法。一种是在DDMS里点Start Method profiling按钮,这种方法监控范围不精确。另一种方法是在代码里加上Debug.startMethodTrace(),然后Debug.stopMethodTrace()结束。完了以后会得到一个.trace的文件,打开视图即可以分析。

在TraceView视图里主要关注两个值,Calls+recurCalls/Total和Cpu Time/Call,分别是调用次数和耗时,然后针对此进行逻辑优化。

2.SysTrace

Systrace是Android4.1及以上版本的性能数据采样和分析工具。它具备以下功能:
(1)它能直观的看到每个线程上API的调用情况,包括耗时和调用顺序。
(2)能直观的看到每条线程的执行情况,包括状态和耗时,能统计CPU里每条线程的耗时。
(3)通过代码插入的方式,可以显示API的耗时和调用关系。(插入代码为Trace.beginSection和Trace.endSection)

3.一些优化建议

(1)缓存一些数据在需要的时候可以更快加载。
(2)把耗时操作移出主线程。


其他方面

1.ListView和RecyclerView优化

(1)在快速滑动时(setOnScrollListener来设置监听快速滑动,状态SCROLL_STATE_FLING),暂停一些后台操作,例如下载图片,加载图片。
(2)复用convertView,在getView里判断它是否为空,不为空就复用。
(3)item减少控件的数量和布局层次。
(4)getView里,代码逻辑要优化,不要做复杂逻辑运算,特别是数据库和网络访问操作。

2.刷新优化

(1)减少刷新频率,比如更新进度时变化太小就不用刷新界面。
(2)避免没必要的刷新,例如数据没有变化的情况下刷新View。
(3)缩小刷新区域,使用invalidate(Rect dirty)或者invalidate(int l, int t, int r, int b)。

3.动画

(1)动画优先选择属性动画,属性动画性能相对于补间动画来说性能更高,能实现的效果也更多,帧动画则是性能最差,消耗最大的。
(2)硬件加速,硬件加速有4个级别,针对需要来设置,分别是Application级,Activity级,Window级,View级(View.setLayerTyoe)。可以将要执行动画的View设置为硬件加速。动画结束再设置LayerTyoe为NONE。


Thanks

https://www.jianshu.com/p/9e095bacf44a