Android 性能优化,内存溢出是两个老生长谈的问题,此篇主要记录在开发中,常用的方法及注意事项。
View 视图层次优化
- ListView/RecyclerView view 重复利用;
- ViewStub: 某些页面,部分UI在一开始的时候不需要呈现,则可以使用ViewStub来保存View,在需要使用到的时候再加载;
- include: 重复利用xml;
- merge: 重复利用xml,降低嵌套层次;
- FrameLayout/LinearLayout/RelativeLayout: 此三种ViewGroup的效率依次降低,效率主要的差别在于 onMeasure 方法,参见文章: http://blog.csdn.net/hejjunlin/article/details/51159419
对于View 层次上来说,还需要注意的是,尽量减少嵌套,能用两层嵌套的,就坚决不使用三层。
自定义View
我们知道调用View.invalidate()会触发View的重绘,但有两个原则需要遵守:
- 仅仅在View的内容发生改变的时候才去触发invalidate方法
- 尽量使用ClipRect等方法来提高绘制的性能
- 减少绘制时不必要的绘制元素,对于那些不可见的元素,我们需要尽量避免重绘
- 不要在onDraw()方法中执行内存分配的操作,如:不要在onDraw()方法中执行Paint mPaint = new Paint();等操作
- 对于不在屏幕上的元素,可以使用canvas.quickReject把他们给剔除,避免浪费CPU资源。另外尽量使用GPU来进行UI的渲染,这样能够极大的提高程序的整体表现性能
Java 代码层次
1、使用SparseArray和ArrayMap代替HashMap(数量级在1k内)
http://blog.csdn.net/u010687392/article/details/47809295
2、Android中别使用enum,使用static final 代替枚举enum,因为使用enum比使用static需要消耗更多的内存空间
Java 性能层次
1、网络请求,如果使用的非常频繁则会对用户手机的电量和流量造成比较大的损耗,正所谓应用的开发应把用户体验放在第一位,所以在网络请求方面,应尽量遵循这两个原则:
- 减少移动网络被激活的时间与次数(保证应用功能正常使用的前提下)
- 对一些与用户交互的比较大的数据(图片、文件等),可以对这些数据进行压缩
2、防止内存抖动,所谓内存抖动就是在短时间内创建出大量的对象,从而造成内存紧张,进而触发GC回收,因为执行GC的回收的时候,所有的线程都会暂停,包括主线程,只有等待GC回收完成后其它操作才能继续进行,通常情况下GC回收的效率是非常高效的,但是如果内存上发生大量内存抖动,那么将会导致GC的回收效率降低。所以内存抖动很可能会造成界面卡顿。
如何防止内存抖动?
- 使用对象池来管理对象,减少对象创建的次数,在使用完成之后再手动释放对象池中的对象
- 不要在for、while等循环体中执行对象的创建
- 避免在onDraw()方法中执行对象的创建
- 采用预分配策略来减少一次性创建大量的数据
预分配:就是在程序刚启动的时候就事先创建一些即将要使用到的数据,这样可以在需要使用到这些数据的时候提供更快的加载速度,这种行为就叫做预分配。
预防内存泄漏
1、Toast中使用getApplicationContext()来代替当前Activity的Context,如Toast.makeText(getApplicationContext(),””,Toast.LENGTH_SHORT).show();
因为如果使用当前Activity的Context,当用户操作不当时,比如在Toast显示时候按了返回键,而此时Toast又持有当前Activity的Context引用,所以导致内存泄漏
2、Android开发中合理的使用static,因为static的生命和应用的生命一样长,如果该变量可以的话则不要用static修饰,让它和Actiity保持一样的生命周期或者和方法保持一样的生命周期
3、Drawable,在使用的时候不要定义成静态的,在ImageView#setImageDrawable的时候,会将Drawable的callback指定成ImageView 本身,如果定义成静态的Drawable,则该静态变量一直持有该ImageView,ImageView又持有Activity(Context),造成Activity无法正常回收
其它
LocalBroadcastManager
http://blog.csdn.net/u010687392/article/details/49744579
线程池
http://blog.csdn.net/u010687392/article/details/49850803
性能优化
http://blog.csdn.net/u010687392/article/details/50035061
http://blog.csdn.net/arui319/article/details/8537588
view.animate().translationY(10).setDuration(300).start();