Android 性能优化

性能优化我们可以分为4个方面优化 如下图:

这里写图片描述

卡顿优化

我们先来了解一个概念:FPS ,FPS表示每秒传递的帧数,在理想情况下,60FPS就能感觉到不卡,这就意味着每个绘制时长大约在16ms,但Android系统很有可能没有办法及时完成那些复杂页面的渲染操作,Android 系统每隔16ms发出VSINC信号,出发对UI进行渲染,如果每次渲染都成功,就可以达到流畅画面所需的60FPS,如果每个操作时间24ms,系统在得到VSINC信号时,就无法及时渲染,这样就发生丢帧的现象,那么用户在32s内将看到一幅画面。这种现象在滑动列表和动画比较常见,还有可能是你的layout比较复杂,层叠太多的绘制单元,无法再16ms中完成绘制,最终引起绘制不及时

优化建议

1.布局优化

布局优化的思想很简单,就是尽量减少布局的层级,这个道理很浅显,布局的层级少了,这就意味android绘制的工作量少了,程序的性能自然就高了

如何进行布局优化,首先要删除布局中无用的控件和层级,其次有选择的使用性能较低的viewgroup,比如Relaitivelayout,如果布局既可以使用LinearLayout也可以使用Relaitivelayout,那么就采用LinearLayout,因Relaitivelayout的功能比较复杂,绘制过程会花费更多的CPU的时间

标签可以将一个制定的布局文件,加载到当前的布局文件,通过这种方法不用吧重复使用的布局文件再写一遍, 标签只支持android:layout_开头的属性,其他属性不支持android:id是特例,如果指定了id,同时包含的布局的跟标签也指定id,那么以标签id为准

标签一般和标签一起使用从而减少布局层级的,如果父布局是LinearLayout,的跟布局也是LinrarLayout那么跟布局就可以换成,减少一层无用的布局

继承了view,它非常轻量级且宽高为0,因此它本身不参与任何布局和绘制过程,viewstub意义在于按需加载所需要的文件,很多布局在正常情况下不会加载,比如网络异常页面,这个时候就没必要在初始化的时候就加载出来,通过viewstub可以做到在使用的时候在加载,提升程序初始化性能,viewstub不支持标签

2 避免过度绘制

过度绘制指的是,屏幕上某一像素在同一帧的时间内,绘制了多次,在多层次重叠UI结构中,如果不可见的UI,也在做绘制工作,就会导致多层某些像素区域被绘制多次,从而浪费了cpu和gpu资源。

如何避免过度绘制
– 布局上的优化,移除xml中非必须的背景,移除window默认背景,按需展示默认图片
– 自定义view优化,利用canvas.clipRect()来帮助系统识别,那些可见区域,只有在这个区域才能被绘制。

3 绘制优化

绘制优化是指View的Ondraw方法,避免执行大量的操作,这主要指两个方面

首先,ondraw中不出创建局部对象,因为ondraw会被频繁调用,这样一瞬间就产生大量的临时对象,这不仅占用了内存,还会导致系统频繁gc,降低执行效率

另一方面ondraw不要执行耗时任务也不能执行成千上万的循环操作,尽管每次循环都是轻量级的,但是大部分魂环还是十分的抢占CPU时间片,造成view绘制不流畅
按照Google官方给出性能优化的标准,view的绘制帧率保持在60fps是最佳的,这就要求每帧的绘制时间不超过16ms,虽然程序很难保持这个时间,但是尽量降低ondraw方法的复杂度总是且还是切实有效的

4 响应速度优化:

响应速度优化核心思想避免在主线程做耗时操作,响应速度过慢更多的体现在Activity的启动速度上,如果在主线程作了太多事情会导致启动activity黑屏现象,android 规定,activity如果5秒钟内无法响应屏幕触摸事件,和键盘输入事件,就会ANR,而BroadcastReceiver10秒钟还未执行完操作也会ANR

内存优化

1 内存泄漏优化

如果在发生内存泄漏后在优化,会加大项目费用,最好在写代码的时候就考虑内存,下面我列出一些可能会导致内存泄漏的场景

– 对 Activity 等组件的引用应该控制在 Activity 的生命周期之内; 如果不能就考虑使用 getApplicationContext 或者 getApplication,以避免 Activity 被外部长生命周期的对象引用而泄露。

– 尽量不要在静态变量或者静态内部类中使用非静态外部成员变量(包括context ),即使要使用,也要考虑适时把外部成员变量置空;也可以在内部类中使用弱引用来引用外部类的变量。

– 对于生命周期比Activity长的内部类对象,并且内部类中使用了外部类的成员变量,可以这样做避免内存泄漏:

将内部类改为静态内部类
静态内部类中使用弱引用来引用外部类的成员变量

– Handler 的持有的引用对象最好使用弱引用,资源释放时也可以清空 Handler 里面的消息。比如在 Activity onStop 或者 onDestroy 的时候,取消掉该 Handler 对象的 Message和 Runnable.

– 在 Java 的实现过程中,也要考虑其对象释放,最好的方法是在不使用某对象时,显式地将此对象赋值为 null,比如使用完Bitmap 后先调用 recycle(),再赋为null,清空对图片等资源有直接引用或者间接引用的数组(使用 array.clear() ; array = null)等,最好遵循谁创建谁释放的原则。

– 正确关闭资源,对于使用了BraodcastReceiver,ContentObserver,File,游标 Cursor,Stream,Bitmap等资源的使用,应该在Activity销毁时及时关闭或者注销。

– 保持对对象生命周期的敏感,特别注意单例、静态对象、全局性集合等的生命周期。

2 优化内存空间
由于物理设备内存空间有限,尽量使用最小内存对象或资源,可以减少内存开销,同时让GC更高效的回收资源
–对象引用,强引用,弱引用,软引用,虚引用,根据不同的业务场景,合理使用
– 减少不必要的内存开销 ,增加内存复用,比如bitmap,lisview复用。

其他优化

listview 和 bitmap优化

线程优化:
线程优化的思想是采用线程池,避免程序中存在大量的Thread,线程池可以重用每部县城,从而避免了线程创建和销毁带来的性能开销,同事线程池还有效的控制线程的最大并发数,避免大量线程因互相抢占系统资源从而导致阻塞的发生,因此实际开发中我们要尽量的使用线程池

一些优化的小建议

1 避免创建过多的对象
2不要用过多的枚举,枚举占用的内存空间比整形要大
3 常量使用static final 来修饰
4 采用内存缓存和磁盘缓存
5 尽量采用静态内部类,这样可以避免潜在的由于内部类而导致的内存泄漏

提高程序的可维护性

这里写图片描述
这里写图片描述
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值