Android app 性能优化之视图优化

Android app 性能优化之视图优化

前言:

每当一款App开始快速扩展的时候,随着业务功能的越来越复杂,功能模块的越来越多总会引起这样那样的性能问题。交互不流畅卡顿,ANR,手机发热量大等等性能问题在Android开发中一直都是一个坑爹的存在。不是大家不想去优化,可能是等你发现开始要搞搞性能的时候,发现工程貌似好大了,能跑不崩就万事大吉了,那么多代码要去看,去改。真心是一个让人想想都糟心的事。也可能,关键点不好找,可能一个性能问题是别的你想都想不到的地方引起的,为了优化这么一个点,可能花费很多时间。总之这么一个复杂,浩大的工作,如果不想做,可以找一万个理由。但是一款精品应用,性能优化会直接影响到你的app是一款什么层次的app,会有多少用户追捧你,可以让你的app提升多少价值。好了,不扯犊子了,言归正传。


基本概念 ——不管是大神还是小白,都建议看看,加深印象。

本期说的是视图优化,那有几个关于渲染的基本概念就不得不提。


渲染性能

大多数用户感知到的卡顿等性能问题的最主要根源都是因为渲染性能。当需求是一些复杂的交互或者是狂拽酷帅屌炸天的特效的时候,Android系统很有可能无法及时完成那些复杂的界面渲染操作。Android系统每隔16ms发出VSYNC信号,触发对UI进行渲染,如果每次渲染都成功,这样就能够达到流畅的画面所需要的60fps,为了能够实现60fps,这意味着程序的大多数操作都必须在16ms内完成。





但是如上所说,如果一个屌炸天的效果处理超过了16ms,系统在得到VSYNC信号的时候就无法进行正常渲染,这样就发生了丢帧现象。那么用户在32ms内看到的会是同一帧画面。




一般来说UI执行动画、或者一个视图突然同时冒出来很多个需要渲染的组件、或者滑动ListView的时候容易引起卡顿,是因为这里的操作相对复杂,容易发生丢帧的现象,从而感觉卡顿。有很多原因可以导致丢帧,也许是因为你的layout太过复杂,无法在16ms内完成渲染,有可能是因为你的UI上有层叠太多的绘制单元,还有可能是因为动画执行的次数过多。这些都会导致CPU或者GPU负载过重。


过度重绘

Overdraw(过度绘制)描述的是屏幕上的某个像素在同一帧的时间内被绘制了多次。在多层次的UI结构里面,如果不可见的UI也在做绘制的操作,这就会导致某些像素区域被绘制了多次。这就浪费大量的CPU以及GPU资源。

一般来说,这个问题应该是大多数app中都普遍存在的问题,可能是层叠组件的使用不合理导致过度重绘,也可能是Layout重复设置背景引起过度重绘。不过这个问题,我们可以很容易的借助手机提供的工具快速的找出来。之后给出工具的使用。


VSYNC

理解App是如何进行渲染的,我们必须了解手机硬件是如何工作,那么就必须理解什么是VSYNC。

在讲解VSYNC之前,我们需要了解两个相关的概念:

  • Refresh Rate:代表了屏幕在一秒内刷新屏幕的次数,这取决于硬件的固定参数,例如60Hz。
  • Frame Rate:代表了GPU在一秒内绘制操作的帧数,例如30fps,60fps。

GPU会获取图形数据进行渲染,然后硬件负责把渲染后的内容呈现到屏幕上,他们两者不停的进行协作。

正常情况这样固然是好,但是问题就是,你程序中的操作,极有可能导致帧率不同步,导致前帧跟后帧重叠,出现图像断裂这样的问题。

就像下面这个图


VSYNC如果要深究还是蛮有意思的,有兴趣的可自行GOOGLE。分享一个VSYNC相关文献。

VSYNC 参考文献

http://blog.csdn.net/michaelcao1980/article/details/43233765

工具篇

    其实能够调优的工具还是很多的。这里就介绍几个比较常用没什么门槛的工具的用法跟技巧。这几个用好,就可以解决很多问题了。


Profile GPU Rendering (GPU呈现模式分析)

这个工具在手机的开发者选项里。可以选择不同的呈现方式

随着界面的刷新,界面上会滚动显示线形图来表示每帧画面所需要渲染的时间

,图越高表示花费的渲染时间越长。

中间有一根绿色的横线,代表16ms,我们需要确保每一帧花费的总时间都低于这条
横线,这样才能够避免出现卡顿的问题。整个分析图分为三部分,蓝色代表测量绘制Display List的时间,红色代表OpenGL渲染Display List所需要的时间,黄色代表CPU等待GPU处理的时间。












举个应用实例

用户中心有个活动标签的小动画即一个热门标签的抖动。进入到页面的时候,发现曲线跳动很厉害,而且每次跳动都超过16ms的基准线。就怀疑是否是这个动画效果实现的不合理。



经过审查代码发现如此简单的一个动画,采用的居然是逐帧动画的方式实现。

<span style="font-family:Comic Sans MS;font-size:14px;"><?xml version="1.0" encoding="utf-8"?>
<animation-list
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:oneshot="false">
	<item
		android:drawable="@drawable/hot_1"
		android:duration="200"/>
	<item
		android:drawable="@drawable/hot_2"
		android:duration="200"/>
	<item
		android:drawable="@drawable/hot_3"
		android:duration="200"/>
</animation-list></span>

逐帧动画的实现方式是在指定时间显示指定的帧图片。逐帧动画固然可以实现很多复杂的动画效果,但是同时也带来了性能问题,因为每次变帧都需要加载新的图片资源。同时,因为帧是自己调的,如果每一帧设置图片变化太大,整个动画开起来就会很不连贯流畅。

对于这种抖动的简单动画,完全可以用补间动画来做,不仅减少了资源的消耗,还可以让整个动画开起来更加流畅。

<pre name="code" class="java"><span style="font-family:Comic Sans MS;font-size:14px;">    private void setHotImgAnimation(View animationView){
        ObjectAnimator shakeAnimator = new ObjectAnimator();
        shakeAnimator.setInterpolator(new LinearInterpolator());
        shakeAnimator.setProperty(View.ROTATION);
        shakeAnimator.setFloatValues(0,45,0);
        shakeAnimator.setDuration(600);
        shakeAnimator.setRepeatCount(ValueAnimator.INFINITE);
        shakeAnimator.setTarget(animationView);
        shakeAnimator.start();
    }</span>


 
 

运行代码看修改后的效果:



从图中可以明显看出GPU呈现的分析图,整个过程变得相对平滑,动画过程也都降到了16ms以下。


Show GPU Overdraw ( 显示GPU过度绘制)



这个工具也可以在开发者选项中找到,打开后,每当你进入一个应用,界面上就会把各个组件花花绿绿的标记出来。这些颜色分别达标什么意思。
蓝色,淡绿,淡红,深红代表了4种不同程度的Overdraw情况,我们的目标就是尽量减少红色Overdraw,看到更多的蓝色区域。

Overdraw有时候是因为你的UI布局存在大量重叠的部分,还有的时候是因为非必须的重叠背景。例如某个Activity有一个背景,然后里面的Layout又有自己的背景,同时子View又分别有自己的背景。仅仅是通过移除非必须的背景图片,这就能够减少大量的红色Overdraw区域,增加蓝色区域的占比。这一措施能够显著提升程序性能。






我们还是来举例说明它的用法:




注:为了更好的呈现OverDraw所带来的性能影响,这里做了个小动作——不停的刷新界面,以便的到充足的GPU性能分析图。

从图中可看出,左边未修改的界面,OverDraw严重,满屏幕飙红,从GPU呈现图上来看,GPU平局渲染时间都超过了16ms的基准。上图造成如此多的过度绘制的主要原因是重复的背景,红色区域上层布局设置了背景,子布局又重复设置背景,导致了过度绘制。将不必要的背景设置出去以后,可以看到,红色标记区域基本消失,从GPU呈现图上来看,GPU平均渲染时间也降低到了16ms的基准线以下。


Android Monitors-Dump View Hierarchy

这个工具在Android Monitors中。
这个功能会把当前界面显示的图截下来,同时在右边展示出当前界面的Display list的详细信息显示出来。通过这些信息,你不仅可以分析视图各个组件的状态,值,大小等,还可以查看当前界面的布局,层级是否合理。
这边我就不再赘述了。



这期的分享就到这里,后续还会更行更多的调优方面的实用工具跟技巧。也希望读者们积极分享在开发过程中找到的比较好的调优方法,让应用变的更加牛逼闪闪。

猜你喜欢

转载自blog.csdn.net/shenjinalin123/article/details/51982794