android 设备作为移动设备,不管是内存还是CPU的性能都受到一定的限制,虽然与单片机相比体现不是那么明显,但从程序的角度来说尽量的节省cpu与内存是对性能的提升是很有必要的,过多的使用cpu与内存资源会出现卡顿,甚至无法响应的情况。
性能优化的有效方式可以从以下方面进行:布局优化、内存泄露优化、绘制优化、响应速度优化、ListView优化、Bitmap优化、线程优化以及一些优化建议。
内存优化中,内存泄露并不会导致程序功能异常,很难被发现,这与开发人员的水平和意识有很大的关系,甚至很难被发现,需要一些内存泄露分析工具--MAT。通过MAT就可以发现一些开发过程中难以发现的内存泄露问题。
布局优化:首先删除布局中无用的控件和层级,其次有选择的使用性能较低的viewGroup。 LineLayout与FrameLayout优于RelativeLayout,消耗更少的cup时间,如果需要FrameLayout与LineLayout,增加布局层级,那还是采用RelativeLayout。另一种手段采用<include>标签、<merge>标签、和ViewStub。<include>标签主要用于布局重用,<merge>标签一般和<include>标签配合使用以减少布局的层级,而ViewStub提供按需加载功能、提高初始化效率。
绘制优化:View的onDraw方法要避免执行大量的操作,主要体现在两个方面。一:onDraw中不要创建局部对象。二:onDraw方法中不要做耗时任务。这是因为onDraw方法可能会频繁的调用,一瞬间产生大量的临时对象或耗时任务会占用过多内存,绘制也不会流通,还会导致系统gc的次数过多,降低执行效率。
内存泄露优化:内存泄露要求开发者经验与意识较高,因此也是最容易出的错误之一。可以从两个方面着手一:避免写出内存泄露的代码,二:通过MAT工具或其它的工具找出潜在的内存泄露,解决内存问题。
主要场景有:
一:静态变量导致内存泄露(Acitivity被静态变量引用时无法正常销毁,相信没有谁会这么搞)
二:单例模式导致的内存泄露(单例模式其生命周期与Applicationg一致,Activity对象出现无法被及时释放)
三:属性动画导致的内存泄露(Acitivity退出属性动画无限循环)
响应速度优化和ANR日志分析 :响应速度优化的思想是避免在主线程中做耗时操作,一般来说触5秒,广播10秒无响应会出现ANR,ANR在代码中很难发现,进程发生ANR系统在/DATA/anr目录下创建一个文件traces.txt,通过分析这个文件定出原因。
ListView和Bitmap优化:主要三个方面:一采用ViewHolder并避免getView中执行耗时操作;二:根据列表滑动状态来控制任务的执行频率;三可以尝试开启硬件加速来使ListView的滑动更流畅。这些也适用于GridView.BitmapFactory.Options的inSampleSize实现根据需要对图片进行采样。
线程优化:采用线程池,避免程序中存在大量的Thread.线程池能重用内部线程,避免创建和销毁带来的性能开销、控制最大并发数避免大量线程因互相抢占系统资源人而导致阻塞。
性能优化的:避免创建过多的对象,不要使用过多的枚举(占内存),常量用static final修饰; 使用android特有的数据结构(如sparseArray和Pair),适当使用软引用和弱引用;采用内存与磁盘缓存;尽量采用静态内部类,这样可以避免潜在的由于内部类而导致的内存泄露。
内存泄露分析mat工具:AndroidStudio的DDMSD 在Monitor中 选择进程,单击Dump HPROF file这个按键 导出hprof-conv通过hprof-conv命令(android sdk 提供的工具)转换一下,MAT最常用的只有Histogram(看内存中不同类型的buffer)和Dominator Tree(按大小排序分析对象之间的引用关系), 选择一个对象,右键Path to GC Roots->exclude wake/soft references.