android应用性能优化
1. UI布局的优化
- 使用include,merge,ViewStub标签优化布局
- 尽量不存在冗余嵌套及过于复杂的布局(譬如10层布局嵌套就会异常)
- 尽量使用GONE替换INVISIBLE
- 使用weight后尽量width和height设置成0dp减少运算
- Item存在非常复杂的嵌套时考虑使用自定义ItemView来取代,减少measure与layout的次数
- Overdraw(过度绘制)描述的是屏幕上的某个像素点在同一帧的时间内被绘制了多次。在多层次的UI结构里面,如果不可见的UI也在做绘制的操作,这就会导致某些像素区域被绘制了多次,这就浪费了大量的cpu以及gpu的资源。
2.代码中的优化
-
android与java的差异api使用
-
枚举
避免在android中使用java的枚举类型,因为编译后不但占空间,加载也费时,完全没有static final的变量好用、高效 -
SparseArray与HashMap
(1)SparseArray(LongSparseArray)比HashMap更省内存,在某些条件下性能更好,主要是因为它避免了对key的自动装箱(int转换为Integer),它内部则是通过两个数组进行数据存储的
(2)内部对数据还采取了压缩的方式来表示稀疏数组的数据,从而节省内存空间
(3)SparseArray在存储和读取数据的时候,使用的是二分查找法,SparseArray存储的元素都是按元素的key值从小到大排列好的,而在获取数据的时候,也是使用二分查找法判断元素的位置,所以在获取数据的时候非常快,比HashMap快的多
(4)虽说SparseArray性能比较好,但是由于其添加、查找、删除数据都需要进行一次二分查找,所以在数据量大的情况下性能会降低,最好在数据量千级以下使用 -
ArrayMap与HashMap
(1)ArrayMap是一个<key,value>映射的数据结构,它的设计上更多是考虑内存的优化,内部也是使用两个数组进行数据存储
(2)和SparseArray一样,也会对key使用二分查找法进行从小到大的排序,在添加、删除、查找的时候都是先使用二分查找法得到相应的index
(3)和SparseArray一样,在数量大的情况下性能会降低 -
Parcelable与Serializable
Serializable的作用是将数据对象存入字节流当中,在需要时重新生成对象,主要应用是利用外部存储设备保存对象状态,以及通过网络传输对象等,而Parcelable是直接在内存中读写,很明显内存的读写速度通常大于IO读写,而且Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC,所以在android中的序列化通常优先使用Parcelable
-
-
StringBuilder和StringBuffer
大部分不考虑线程安全的时候直接使用StringBuilder要更高效
-
Handler的内存泄漏
发送消息时尽量使用obtain去获取已经存在的message对象进行复用,而不是new Message对象,这样可以节省内存
退出时注意调用Handler的removeCallbacks和removeMessages避免内存泄漏 -
Service和IntentService
在使用后台Service时尽量将能够替换为IntentService的地方替换掉,这样可以减少系统压力,省电,省内存,省cpu占用
-
变量引用的优化
在当前类内部中尽量不用通过自己的getXXX、setXXX对自己的内部成员进行操作,而是直接使用,这样可以提高代码执行效率,不要一味的为了设计模式而过分的抽象代码,因为代码抽象系数与代码加载执行时间成正比
-
使用LocalBroadcastManager代替BroadcastReceiver
LocalBradcastManager发送的广播只会在App内传播,不会泄露给其他App,确保隐私数据不会泄露,其他App也无法向你的App发送该广播,不用担心其他App过来搞破坏,而且LocalBroadcastManager比BroadcastReceiver更高效
-
尽量避免在经常调用的方法、循环中new对象
由于系统不仅要花费时间来创建对象,而且还要花时间对这些对象进行垃圾回收和处理,在我们可以控制的范围内,最大限度的重用对象,最好能用基本数据类型或数组来代替对象
-
对Map和List初始化的时候,如果知道容量大小,最好把容量填上
如:ArrayList<String> list = new ArrayList<String>(100);
避免在容量不够的时候自动扩容(2倍扩容)浪费内存 -
避免非静态内部类
当你创建并实例化一个非静态内部类的时候,你就建造了一个指向外部类的隐含引用,如果这个内部类的实例比外部类存活的时间还要长,那即使不需要这个外部类,它还是会保存在内存中。例如,在Activity类中创建了一个扩展AsynTask的非静态类,开始处理异步任务,在运行过程中杀掉了这个Activity,只要这个异步任务还在运行,这个Activity也会一直存活,无法释放内存
-
Activity的内存泄漏
这是android中最常见的的内存泄漏,也是非常昂贵的泄漏,因为他们里面包括了UI中所有的视图层级,这占用了很多内存空间,有很多操作都需要一个Context对象,通常用一个Acitivty来传递这些信息,要确保你理解了那个Activity上发生了什么,如果一个指向他的引用被缓存了,而且这个对象要比Activity生成时间更长,若不清除这个引用,就会造成内存泄漏,所以大部分时候能用Application太代替很多地方的Context传值
例如static Resources res = activity.getResources();把这个缓存为一个全局静态变量,则会造成activity无法被回收 -
Json与XML
网络数据通常使用Json格式,而不选xml,同样的数据,json的格式比xml的数据量要小,而且解析速度也更快
-
有很多优化,其实就是时间和空间的平衡问题,有时候需要以时间换空间,有时候需要以空间换时间。经常需要在内存使用和运行效率的中间寻找一个平衡点