说到android性能优化,总觉得是一个很模糊的东西,因为app的性能始终适合手机本身的性能挂钩的,也许一些消耗内容的操作,在一些移动设备可以运行,但是在另外一些上面就会出现内存溢出的问题,但是不管怎么说,但问题出现的时候,我们应该有解决的办法,最起码有解决办法的思路,下面就是聊聊android性能一些问题。
首先是三个名称:内存泄漏,内存溢出(OOM),应用程序无响应(ANR)。
我们知道,android手机上运行app其实很多时候(只是很多时候),每个app都运行在一个进程中,这个进程是设备给应用程序分配的,其实你也可以理解为,每个应用程序运行在一个设备为我们分配的虚拟机(dalivk虚拟机)中,这样一来,其实每个程序能够给我们使用的内存是设备分配给我们的。而每个进程中可以并且只有一个线程,这个线程就是主线程(也叫UI线程)。如果我们在这个主线程中做太多的耗时操作,就会引起操作的卡顿这些问题。如果严重的话就会引起应用程序无响应(ANR)。
内存泄漏就是,我们的程序在申请内存后(比如实例化对象),在使用结束后,不能及时释放掉这些内存。一般内存泄漏单次不会有太多问题,但是太多的内存泄漏会导致太多无用的内存占有,这个时候有可能会导致内存溢出(OOM)。
内存溢出分两种情况,第一种,我们为一个对象分配的空间不够本对象使用,比如实例化了一个integer对象,但是放入一个更大的对象。第二个就是虚拟机内存被占满。
那么如何解决这些问题呢,这里只是一些思路:
1、在使用布局的时候,使用简单布局。有两种情况,第一种,劲量不要嵌套太多的无用布局,这样不会在CPU运算时做太多无用的计算,第二个,就是在使用布局的时候,劲量使用简单的viewgrounp,在这里复杂程度的排序:RelativeLayout大于LinearLayout和FrameLayout。
2、在使用布局的时候,多使用<include>、<merge>和ViewStub。一般<include>和<merge>配合使用,这样就不必过多的重复使用一段代码,这样就会不至于CPU重复运行一段布局。ViewStub是在有需求的时候在加载布局,比如一个界面中有一段布局默认是不显示的,但是当我们需要时候的时候需要显示,这个时候假如我们不使用的时候也加载这段代码就是不合适的。这个时候使用ViewStub就好。
3、使用静态变量的时候劲量使用final,或是说劲量少的使用静态变量,我们知道静态变量不会随着调用它的程序结束而消失,这会导致一定程度上的内存泄漏。
4、使用属性动画的时候在Activity结束的时候,要使用animator.cancel()来停止动画,因为有些动画是无限循环的,在调用他的程序都结束的时候,他还会一直循环,这个时候也会造成内存泄漏。
5、在自定义view或viewgrounp的时候,不要在onDraw中做太多的耗时操作,因为这样会导致view的绘制过程不流畅,导致一种卡卡的感觉。
6、不要在onDraw方法中定义局部变量,因为在view绘制的工程中,onDraw方法会多次调用,这样会多次创建局部变量,对内存造成不必要的浪费。
7、对listview等的优化,在自定义Adpter的时候,使用holder,这样可以重复调用已经实例化好的对象,而不会重复实例化对象。同时在getView中不要做耗时操作,这样会使listview等整体加载流畅。
8、劲量少的使用枚举,枚举占用的空间比整形大。
9、少的创建对象,因为创建对象就会对应的创建堆内存和栈内存,基本我们不调用不赋值,也会创建堆内存。
10、劲量多的使用内存缓存和磁盘缓存,如使用LruCache等,这样可以使一些资源重复调用。
11、适当使用软应用和弱应用。
12、使用线程的时候,使用线程池,这样可以避免大量的创建线程和销毁线程的操作。
出现ANR的时候,我们可以使用系统在/data/anr里面产生的日志traces.txt进行分析。使用命令:adb pull /data/anr/traces.txt,就可以打开查看日志了。
内存泄漏的问题,我们可以使用MAT工具进行分析。
关于性能优化,其实有数不尽的需要注意的地方。毕竟永远都没有最优只要更优。也欢迎各位补充。