Android的性能优化方法

Android程序不可能无限制地使用内存和CPU资源,过多地使用内存会导致程序内存溢出,即OOM(Out of Memory);而过多地使用CPU资源,一般是指做大量的耗时任务,会导致手机变得卡顿甚至程序无法响应的情况,即ANR(Application not Responding)。

因此,Android程序的性能问题就变得异常突出了。那么下面我们就介绍一些有效的性能优化方法,主要内容包括:布局优化、绘制优化、内存泄漏优化、响应速度优化、ListView优化、Bitmap优化、线程优化以及一些性能优化建议

一、布局优化。布局优化的思想很简单,就是尽量减少布局文件的层级。
1、有选择地使用性能较低的ViewGroup,比如RelativeLayout。如果布局中既可以使用LinearLayout也可以使用RelativeLayout,那么就使用LinearLayout,因为RelativeLayout比较复杂,它的布局过程需要花费更多的CPU时间。FrameLayout和LinearLayout一样都是一种简单高效的ViewGroup,因此也可以多使用FrameLayout。
2、通过标签、标签和ViewStub。
标签主要用于布局重用,可以将一个指定的布局加载到另一个布局中,使用方式刑如:
注意:标签只支持以android:layout_开头的属性,android:id除外
标签,一般和标签结合使用从而减少布局的层级
ViewStub,首先介绍一下ViewStub,ViewStub继承自View,它非常轻量级并且宽/高都是0,因此它本身不参与任何的布局和绘制过程。它的意义在于按需加载所需布局文件,这在实际开发中将很有意义,比如我们可以用ViewStub加载网络异常时的界面,因为网络异常时的界面通常情况下不会出现,那么就没必要在程序初始化时就加载,这样便提高了程序的性能。考虑篇幅问题,ViewStub的具体如何使用在这里遍不展开了,大家可以查阅相关资料。

二、绘制优化,指View的onDraw方法要避免执行大量的操作,主要体现在两个方面:
1、onDraw中不要创建新的局部对象。这是因为onDraw方法可能会被频繁地调用,这样就会在一瞬间产生大量的临时对象,这不仅占用了过多的内存而且还会导致系统更加频繁地gc,降低了程序的执行效率。
2、onDraw方法中不要做耗时操作,也不能执行成千上万次的循环操作,因为这样会导致View的绘制过程不流畅。按照Google官方给出的性能优化典范中的标准,View的绘制帧率保证60fps是最佳的,这就要求每帧的绘制时间不能超过16ms(16ms = 1000 / 60)。

三、内存泄漏优化。内存泄漏的优化分为两个方面,一方面是在开发过程中避免写出有内存泄漏的代码,另一方面是通过一些分析工具(比如MAT)来找出潜在的内存泄漏继而解决问题。这里主要对第一个方面进行展开。下面列举了一些场景:
1、静态变量导致的内存泄漏。需要合理谨慎地使用静态变量(比如说不能因为将某个变量声明成static的而导致Activity无法被释放或者销毁)
2、单例模式导致的内存泄漏。如果我们在编程的时候不注意,是有可能由单例模式导致内存泄漏的。比如:当前Activity对象被单例模式的TestManager所持有,而单例模式的生命周期是与Application一样长的,所以这就造成了Activity无法被释放,从而产生内存泄漏。
3、属性动画导致的内存泄漏。属性动画中有一类无限循环的动画,针对此类动画需要注意使用,避免造成内存泄漏。

四、响应速度优化。其核心思想是避免在主进程中做耗时操作。Android规定,Activity如果5秒钟之内无法响应屏幕触摸事件或者键盘输入事件就会出现ANR,BroadcastReceiver如果10秒钟之内还未执行完操作也会出现ANR。
因此,我们是将耗时操作放到工作线程中去,采用异步的方式。
另外我们可以通过ANR日志进行分析。当一个进程发生了ANR后,系统会在/data/anr目录下创建一个文件trances.txt,我们可以通过分析这个文件定位出ANR的原因。

五、ListView优化
1、View的复用。
2、结合在自定义适配器中定义的内部类ViewHolder,减少findViewById等的使用。
3、分页加载。当加载的数据量很大时,若一次性从网络加载完再显示,用户可能要等很长时间,这样便造成用户体验不好,另外,还可能造成OOM。

六、Bitmap优化
关于Bitmap的优化,这里主要涉及到二次采样,主要是通过BitmapFactory.Options来根据需要对图片进行采样,采样过程中主要用到了BitmapFactory.Options的inSampleSize参数。限于篇幅,关于二次采样这里就不展开。

七、线程优化
线程优化的思想是采用线程池,避免程序中存在大量的Thread。线程池可以重用内部的线程,从而避免了线程的创建和销毁所带来的性能开销,同时线程池还能有效地控制线程池的最大并发数,避免大量的线程因互相抢占系统资源从而导致阻塞现象的发生。因此,在实际开发中,我们要尽量采用线程池,而不是每次都要创建一个Thread对象。

八、其他性能优化建议
1、避免创建过多的对象。
2、不要过多使用枚举,枚举占据的内存空间要比整型大。
3、巧用final关键字。
4、优先考虑系统提供的api。

猜你喜欢

转载自blog.csdn.net/zdj_develop/article/details/66478718