Android性能优化系列之渲染优化

众所周知的Android系统每隔16ms重新绘制一次activity,也就是说你的app必须在16ms内完成屏幕刷新的所有逻辑操作,这样才能达到60帧/s。而用户一般所看到的卡顿是由于Android的渲染性能造成的。 本篇博客将介绍Android的渲染相关知识。

然而有的时候你的程序会出现这样的情况,如果某个绘制操作超过了16秒用了24秒这时候用户看同一张图片花了32秒而不是16s,用户会感到卡顿,这种现象我们叫-丢帧

Android的渲染机制

首先我们要了解android的渲染机制,android 的渲染主要分为两个组件

1.CPU

2.GPU

由这两者共同完成在屏幕上绘制

Activity如何将复杂的UI转换成用户看得懂的图像并绘制到屏幕上?

这是由格栅化操作完成的,所谓的栅格化就是绘制那些Button,Shape,Path,String,Bitmap等组件最基础的操作。它把那些组件拆分到不同的像素上进行显示,说的俗气一点,就是解决那些复杂的XML布局文件和标记语言,使之转化成用户能看懂的图像,但是这不是直接转换的,XML布局文件需要在CPU中首先转换为多边形或者纹理,然后再传递给GPU进行格栅化,对于栅格化,跟OpenGL有关,格栅化是一个特别费时的操作。

简单理解android的渲染过程

CPU在图像绘制之前向GPU输入这些指令这一过程通过OpenGL-ES

也就是说在屏幕绘制UI对象的时候都需要在CPU中转化成多边形再传递GPU进行格栅化操作

cpu将对象转换为多边形耗时 同样上传到GPU也耗时所以我们要减少对象转换次数以及上传数据的次数,幸运的是OpenGL-ES API允许数据上传到GPU进行数据保存,当下一次绘制按钮的时候只要在CPU的存储器里引用它

所以渲染性能的优化就是尽快的上传数据到GPU尽可能长的在不修改数据的条件下保存数据

虽然android系统已经完成的大部分的优化但是还有一个问题造成了性能的影响–>过度绘制(OverDraw)

过度绘制(overdraw)检测

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

当设计上追求更华丽的视觉效果的时候,我们就容易陷入采用越来越多的层叠组件来实现这种视觉效果的怪圈。这很容易导致大量的性能问题,为了获得最佳的性能,我们必须尽量减少Overdraw的情况发生。

按照以下步骤打开Show GPU Overrdraw的选项:设置 -> 开发者选项 -> 调试GPU过度绘制 -> 显示GPU过度绘制

蓝色,淡绿,淡红,深红代表了4种不同程度的Overdraw情况,

蓝色: 意味着overdraw 1倍。像素绘制了两次。大片的蓝色还是可以接受的(若整个窗口是蓝色的,可以摆脱一层)。

绿色: 意味着overdraw 2倍。像素绘制了三次。中等大小的绿色区域是可以接受的但你应该尝试优化、减少它们。

淡红: 意味着overdraw 3倍。像素绘制了四次,小范围可以接受。

深红: 意味着overdraw 4倍。像素绘制了五次或者更多。这是错误的,要修复它们。

我们的目标就是尽量减少红色Overdraw,看到更多的蓝色区域。

优化过渡绘制区域

下面我们通过一个例子来优化过度绘制,我们使用上面的方法,定位过度绘制的地方

从图上可以看出,按照过渡绘制从好到坏(蓝-绿-粉红-红)来看,文件管理器的过渡绘制是非常严重的,而设置界面的过渡绘制则在可以接受的范围内.下面就以文件管理器为主要分析对象,来看看如何对文件管理器的过渡绘制进行优化.

从文件管理器的图,分析出过渡绘制区域

首先看最上面的ActionBar,对比设置界面的ActionBar就可以知道,整个文件管理器存在一个不透明的背景,导致每次绘制时,都要先绘制这个看不见且不透明的背景.这个背景一般是应用的主题自带的背景,所以GPU过渡绘制显示其位蓝色,这个背景是可以进行优化的.

中间的内容部分,最底层是绿色,说明进行了2x的过渡绘制,去掉第一条我们提的那个全局背景,还有一层背景,也就是1x的过渡绘制,对比setting可知,这个背景色也是可以去掉的.

最容易看出的是这两条,我们先分析和优化这两条,然后再进行其他的优化.

优化过渡绘制区域

在进行位置确认后,我们大概确定了过渡绘制的区域,让我们来使用工具来进行验证和View确认.

打开Monitor(Eclipse和Android Studio中都有快捷打开按钮,即DDMS,右上角选择 Hierarchy View,大概使用如图

其中根节点:PhoneWindos$DecorView是整个视图的根节点,唯一的子节点是ActionBarOverlayLayout,这个Layout包含了ActionBar,应用程序,以及SmartBar.

下面讲述如何从Hierarchy View结合代码分析出需要进行修改的区域

去除默认背景

上面分析过渡绘制区域的第一条,整个window存在一个背景,所以进行了一次重绘,这个背景的重绘是系统级别的,和主题有关,即这个背景是属于ActionBarOverlayLayout的.这种类型的过渡绘制解决也比较方便,在文件管理器的主Activity的onCreate方法中,加入

this.getWindow().setBackgroundDrawableResource(android.R.color.transparent);

就可以将这个看不见的主题背景去掉.下面是去掉主题背景后的效果图:

对比优化前的图可以发现,背景被去掉之后,少了一层过渡绘制. ActionBar上的蓝色已经消失了.中间的内容由绿色变为蓝色

消除子控件背景

上面分析的第二条说”中间的内容部分,最底层是绿色,说明进行了2x的过渡绘制”,现在中间部分变成了蓝色,但是这是一个全局的背景,导致右边的view拉过来之后,还是存在大量的红色和绿色. 继续分析Hierarchy View,找到中间view对应的视图:DragRelativeLayout,查看源码可知,DragRelativeLayout继承自公共控件:SlidingMenu ,SlidingMenu 由CustomViewAbove和CustomViewBehind组成,前者是上面可以左右拉动的那部分,后者是底部不能拉动的那部分(这个从HierarchyView中也可以看出来:如下图所示:

点击CustomViewBehind,查看其所占的区域,就可以发现背景是这个View进行绘制的,打开CustomViewBehind的代码可以发现其构造函数中包含下面的代码:

setBackgroundColor(getResources().getColor(R.color.mz_slidingmenu_background_light));

这个背景是不需要的,查看源码可知,这个view会在SlidingMenu.setMenu的时候,被覆盖掉,还是看不到的.所以这一层view是可以去掉的.下面是去掉一层背景之后的预览图:

可以看到这一层背景去掉之后,过渡绘制减轻了很多.

接着进行分析,可以看到CustomViewAbove也是存在一个过渡绘制的背景的,查看Hierarchy View的CustomViewAbove的子节点,可以看到过渡绘制是由ListView导致的.其id为:FilesList,在代码中找到它,并对他进行分析.在我将PartitionItemLayout中onDraw()函数的setBounds去掉之后,过渡绘制进一步改善了(但是ListItem的View的颜色也比之前要浅了,这一步优化需要根据具体情况进行) 下面是优化后的效果图:

通过调整,已经发现绘制优化了很多

Android渲染优化工具介绍

使用Lint优化代码

Lint工具的使用比较简单,根据给出的提示做对应的修改即可.有时候需要工具具体情况来确定是否需要修改. 下图是一个简单地例子.箭头处提示这个Layout或者它的父Layout是不必须的.具体修改方法即去掉FrameLayout,将RelativeLayout提升为根VIew即可.

Lint工具还会针对代码中潜在的不合理或者Bed Code做出修改意见.比较重要的提示包括

1.声明但是没有使用的变量

2.可能会产生的空指针

3.没必要书写的return,continue

4.复杂代码的简化写法

5.for循环的简化写法:foreach

6.无效的判空

7.空if

8.无效或者未使用的import

使用Tracer For OpenGL ES

Tracer工具也在Android Device Monitor中.点击右上角的Tracer for OpenGL ES按钮就可以进入(如果没有这个按钮,点击旁边的Open Perspective按钮,从选项中选择Tracer for OpenGL ES即可).初次打开Tracer工具,里面是没有内容的,点击右上角的两个按钮(一个是打开现有的GLTrace文件,另一个是新建GLTrace文件)。点击Trace按钮, 手机会自动启动应用程序并启动对应的Activity,当手机上的内容完全绘制出来之后,就可以点击Stop按钮,生成GlTrace文件.文件会自动打开.

分析GLTrace文件,下图是优化过后的图,对比优化前的图可以发现,优化后不会去绘制默认的背景图和CustomViewBehind的背景图.

这只是一帧的绘制,如果多操作几下生成多个帧的绘制trace文件,会发现这两个背景会被多次的重绘,去掉后不仅会减轻过渡绘制,也会加快GUP的绘制速度.

时间: 2024-08-04 17:17:48

Android性能优化系列之渲染优化的相关文章

Mysql优化系列之数据类型优化

本篇是优化系列的第一篇:数据类型 为了不产生赘述,尽量用简洁的语言来描述. 在选择数据类型之前,首先要知道几个原则: 更小的通常更好 尽量使用可以正确存储数据的最小数据类型.更小的数据类型意味着更快,占用更少的磁盘,内存以及缓存,以及处理时间 简单就好 这是出于操作数据类型的效率和代价考虑.整型比字符型操作代价更低,因为字符集和校对规则是字符处理比整型更复杂 两个例子:使用Mysql内建的datatime而不是字符串存储时间,使用整型而不是IP字符串存IP地址 尽量避免NULL 这是个很烦人的值

APP性能优化系列:内存优化-bitmap详解

??在Android应用开发中,我们经常需要跟图片打交道,而图片一个很麻烦的问题是占用内存非常大,经常导致OOM,了解Bitmap相关信息,不同sdk版本中Android图片处理的变化,以及一些优化处理的方式对我们平时开发中对图片的会非常有帮助. ??在开始本节的内容之前我们.先来区分几个名词的概念: Drawable:通用的图形对象,用于装载常用格式的图像,既可以是PNG,JPG这样的图像, 也是前面学的那13种Drawable类型的可视化对象!我们可以理解成一个用来放画的--画框! Bitm

Android优化系列之ListView优化详解

本文内容:adapter,listview的优化,RecycleBi,n优化情况对比,google大会推荐优化, 实现ListView的过程,Adapter起到了至关重要的作用,不仅仅因为getview()方法.那么,先从Adapter说起~ Adapter: 它在ListView和数据源之间起到桥梁的作用,避免listview和数据源直接接触,而导致因为数据源的复杂性使listview显得臃肿. Adapter,适配器,把复杂的数据源适配给listview,很容易联想到适配器模式.   下面是

PLSQL_性能优化系列04_Oracle Optimizer优化器

2014-09-25 BaoXinjian 一.摘要 1. Oracle优化器介绍 本文讲述了Oracle优化器的概念.工作原理和使用方法,兼顾了Oracle8i.9i以及最新的10g三个版本.理解本文将有助于您更好的更有效的进行SQL优化工作. 2. RBO优化器 RBO是一种基于规则的优化器,随着CBO优化器的逐步发展和完善,在最新的10g版本中Oracle已经彻底废除了RBO. 正在使用Oracle8i或9i的人们或多或少的都会碰到RBO,因此在详细介绍CBO之前,我们有必要简单回顾一下古

Android性能优化系列之apk瘦身

Android性能优化系列之布局优化 Android性能优化系列之内存优化 为什么APK要瘦身.APK越大,在下载安装过程中,他们耗费的流量会越多,安装等待时间也会越长:对于产品本身,意味着下载转化率会越低(因为竞品中,用户有更多机会选择那个体验最好,功能最多,性能最好,包最小的),所以apk的瘦身优化也很重要,本篇博客将讲述apk瘦身的相关内容. 包体分析 在Android Studio工具栏里,打开build–>Analyze APK, 选择要分析的APK包 可以看到占用空间的主要是代码.图

Android性能优化系列之App启动优化

Android性能优化系列之布局优化 Android性能优化系列之内存优化 Android性能优化系列之apk瘦身 应用的启动速度缓慢是我们在开发过程中常常会遇到的问题,比方启动缓慢导致的黑屏.白屏问题,本篇博客就将介绍App启动优化的相关知识. 应用的启动方式 通常来说,启动方式分为两种:冷启动和热启动. 1.冷启动:当启动应用时.后台没有该应用的进程.这时系统会又一次创建一个新的进程分配给该应用.这个启动方式就是冷启动. 冷启动由于系统会又一次创建一个新的进程分配给它.所以会先创建和初始化A

Android 性能优化的方面方面都在这儿

又到周六了,鸿洋的不定期的周六放送又来了~~这次来谈谈性能优化吧.大家在工作中或多或少都会拿自家的应用和竞品app做比对,不可避免的需要做一些app性能优化的活.很多时候可能是策略上的调整,不过还是有非常多的通用的方式. 一般情况下,我们谈性能优化基本上会从以下几个方面: App启动速度优化 UI流畅度优化 内存优化 apk瘦身 电量优化 还有些网络速度优化.以及特定类型app的一些针对性的优化,比如播放器起播速度等... 我们重点谈论上面5个方面. 性能优化正常的流程是,发现自己某方面与竞品差

Android性能优化之被忽视的优化点

对于性能优化这个知识点来说,实在是太广了,博主本人也一直非常关注这方面的学习,而对于性能优化来说它包括了非常非常非常多方面,比如:I/O的优化.网络操作的优化.内存的优化.数据结构的优化.代码层次的优化.UI渲染优化.CPU资源使用率的优化.异常处理的优化等等等等... 本篇文章就博主本人的理解来讲述一些在Android开发中可以优化的地方 ArrayList和Vector ArrayList和Vector都是内部以数组实现的List,它们两唯一的区别就是对多线程的支持,ArrayList是线程

【前端优化之渲染优化】大屏android手机动画丢帧的背后

前言 上周我与阿里的宇果有一次技术的交流,然后对天猫H5站点做了一些浅层次的分析,后面点时间基本天天都会有联系,中途聊了一些技术细节.聊了双方团队在干什么,最后聊到了前端优化.因为我本身参与了几次携程H5站点的优化,在这方面有一些心得,但是与宇果交流的过程中发现我们在优化的时候忽略了一些细节. 携程做优化的时候整个重心基本放到了尺寸的缩减,和宇果的交流过程中他提出了渲染优化,其实渲染优化无非是减少回流,对于减少回流我们也有一些概念,我一直认为这个事情应该业务开发关注而不是框架关注(事实上框架也无