Android性能优化
Android性能优化
Android设备作为一种移动设备,不管是内存还是GPU的性能都收到了一定的限制,无法像PC设备那样具有超大的内存和高性能的CPU。Android程序不可能无限制地使用内存和CPU资源,过多地使用内存会导致内存溢出,即OOM;过多地使用CPU资源,一般是指做大量耗时任务,会导致手机变得卡顿甚至导致程序无法响应,即ANR。
性能优化中一个很重要的问题就是内存泄露,内存泄露并不会导致程序功能异常,但是它会导致Android程序的内存占用过大,提高内存溢出的发生几率。
另外,在做程序开发时,除了要完成功能开发、提高程序的性能以外,还有一个一个问题也是不容忽视,那就是代码的可维护性和可扩展性。
1、Android的性能优化方法
1)、布局优化
布局优化的思想,尽量减少布局文件的层级,布局文件层级少了,这就意味着Android绘制时的工作量少了,那么程序的性能就高了。
如何进行优化?首先删除布局中无用的布局和层级,其次有选择地使用性能比较低的ViewGroup,例如RelativeLayout,如果布局中既可以使用LinearLayout也可以用RelativeLayout,那么就采用LinearLayout,因为RelativeLayout功能比较复杂,它的过程需要花费更多的CPU时间。
FrameLayout和LinearLayout一样都是一种简单高效的ViewGroup
布局优化的另外一种手段是采用<include>标签、<merge>标签和ViewStub。
<include>标签:主要用于布局重用,可以将一个指定的布局文件加载到当前的布局文件中。
<merge>标签:<merge>标签一般和<include>标签一起使用从而减少布局的层级。通过<merge>标签就可以去掉多余的那一层LinearLayout。
ViewStub:ViewStub继承了View,它非常轻量级且宽高都是0,因此它本身不参与任何的布局和绘制过程。ViewStub的意义在于按需加载所需的布局文件,在实际开发中,有很多布局文件在正常情况下不会显示,比如网络异常页面。
2)、绘制优化
绘制优化是指View的onDraw方法要避免执行大量的操作!
①、onDraw中不要创建新的局部对象,因为onDraw方法可能会被频繁调用,会瞬间产生大量的临时对象,不仅占用了过多的内存而且还会导致系统更加频繁gc,降低了程序的执行效率;
②、onDraw方法中不能做耗时的任务,也不能执行成千上万的循环操作。尽管每次循环都很轻量级,但是大量的循环仍然十分抢占CPU的时间片,这会造成View的绘制过程不顺畅。
3)、内存泄露优化
一方面在开发过程中避免写出有内存泄露的代码;另一方面是通过一些专业的分析工具比如:leakCanary、MAT来找出潜在的内存泄露并解决
内存泄露:本质是长生命周期的对象一直持有短生命周期的对象的引用,导致短生命周期对象无法及时被释放,没有及时被gc回收。
①、静态变量导致的内存泄露;②、单例模式导致的内存泄露、③、属性动画导致的内存泄露
4)、响应速度优化和ANR日志优化
响应速度优化的核心思想是避免在主线程中做耗时的操作,把耗时的操作放到子线程中执行,通过Handler实现线程间的通信。
5)、ListView和Bitmap优化
ListView的优化:首先采用ViewHolder并避免在getView中执行耗时操作;其次是根据列表的滑动状态来控制任务的执行频率;最后可以尝试开启硬件加速来加速来使ListView的滑动更加顺畅。
Bitmap的优化:主要是通过BitmapFactory.Options来根据需要对图片进行采样,采用过程主要用到了BitmapFactory.Options的inSampleSize参数。
6)、线程优化
线程优化的思想是采用线程池,避免程序中存在大量的Thread。线程池可以重用内部的线程,从而避免了线程的创建和销毁说带来的性能开销,同时线程池还能有效控制线程池的最大并发数,避免大量的线程因互相抢占系统资源从而导致阻塞现象的发生。
7)、性能优化建议
避免创建过多的对象
不要过多使用枚举,枚举占用的内存空间要比整形大
常量请使用static final 来修饰
使用一些Android特有的数据结构,比如:SparseArray和Pair,它们都具有更好的性能
适当使用软引用和弱引用
采用内存缓存和磁盘缓存
尽量采用静态内部类,这样可以避免潜在的由于内部类而导致的内存泄露。
2、内存泄露工具分析
检测界面卡顿的开源工具:BlockCanary
3、提高程序的可维护性
Android的程序设计思想,主旨是如果提供代码的可维护性和可扩展性。代码风格、代码的层次性和单一职责、面向对象、设计模式。