如何对Android进行性能优化

Android的性能优化多少能代表一个程序员的级别,如果面试的时候,面试官问到你,你是如何对android进行性能优化的,你若简单的敷衍两句,那基本认定你就是个初级的程序员了。所以作为资深的android工程师,了解性能优化是我们要走的第一步。

主要方式布局优化、绘制优化、内存泄漏优化、ListView优化、Bitmap优化、线程优化及一些性能优化的建议。

布局优化:1、如果既能用LinearLayout,也能用RelativeLayout,那么就使用LinearLayout,因为LinearLayout和FrameLayout都是简单高效的轻量级ViewGroup,而RelativeLayout设计的参数及绘画细节相对复杂(当然功能也更强大),所以是一种相对重量级的ViewGroup,但是如果需要嵌套增加布局层数,同样会降低程序的性能,这种情况有限考虑RelativeLayout。但是最终还得尽量使用少的层级去实现复杂的页面。
                    2、另一种手段就是采用<include>标签、<merge>标签和ViewStub。 <include>主要用于页面的重用,而<merge> 标签配合<include>标签可以降低减少一层布局层数。而ViewStub提供了按需加载的功能。当需要时才会将ViewStub中的布局加载到内存,这提高了程序初始化的效率。比如网络异常的时候,没有必要每个页面都加载进来然后设置为gone,通过ViewStub就可以实现在使用的时候再加载。
绘制优化:指的是View的onDraw方法要避免执行大量的操作,主要有两点:
           一、尽量不要在Draw中创建新的对象,因为Draw短时间会执行多次,会照成内存突然出现大量的临时对象,不仅占用过多的内存,而且导致系统频繁的gc,降低效率。
           二、不要在Draw中做耗时的任务,哪怕是大量的循环操作。大量的循环依然抢占cpu的时间片,也会影响绘制过程不流畅。
内存泄漏优化:内存泄漏是开发者常常遇到的问题,资源得不到gc的回收,虽然不会照成系统崩溃,用户几乎感觉不到,但是大量的内存泄漏最终会导致内存溢出,严重了同样会崩溃。简单的了解可能会出现的内存泄漏现象
          一、静态变量导致内存泄漏:应该所以开发者都知道这点。但是开发中却未必注意到了, 比如在当前的Activity中,你声明了一个static的Context mContext;然后在onCreate中进行复制mContext = this;这样就好导致当前Activity应用无法被回收,因为gc在当前Activity的对象树中发现mContext一直被持久化(被自己持有了),虽然这样的方法没人会写,但难保有人给View设置为static,这依然导致当前的Activity无法被回收。包括当前Activity中的所有对象和数据。
          二、单例模式导致内存泄漏:如果你设置了一个单例模式的电量管理类,然后向管理方法传入了一个context,那么你的这个Activity同样不能得到释放,除非在onDestory的时候让管理类取消对context的持有。
          三、属性动画导致内存泄漏:Android3.0以后google提供了属性动画,属性动画相比View动画和帧动画的区别在于,能改变当前组件的属性,既然能改变他的属性,那它肯定持有了对View的引用,不然凭什么能改变组件的宽高和位置。如果你的属性动画在Activity退出之后仍未停止,那么恭喜你!又泄漏了。这句代码看似简单无奇animator.cancle(); 却有不少人遗忘,直到工具检测出来才发现。
那出现内存溢出后如何检测出来呢:
我常用的方式就两种:一种是Android Studio自带的MAT工具。当然这工具eclipse也有。第二种就是使用LeakCanary插件,用法也很简单。个人觉得要想深入的挖掘泄漏的问题,还得熟练使用MAT工具,因为他强大了。
ListView优化:无人不晓。这里没什么可说的。话说现在都用RecycleListView了,谁还用adapter,
Bitmap优化: 我们拿一张1024*1024的图片来说,如果是采用ARGB8888(Picasso就是如此)配置加载如内存,那么他的内存消耗是非常大的,8888是代表透明度(Alpha)、 Red )、绿(Green)、蓝(Blue)这四种数据分布用八位字(bit)处理,即一位 字节 (byte),就是说每个像素有4个8bit的内存来分布,即4byte,那么整张图就是4* 1024*1024 =4M,如果你是一个viewpager的启动页,那么一启动光着几张图片至少占用4*3=12M,外加应用自身的内存消耗,可能低配的手机直接OOM,这个时候要做的就是图片压缩,大致步骤是:首先通过BitmapFactory.Options.inJustDecodeBounds设置为true,获取图片的基本信息长、宽等,拿到长宽数据后针对要压缩的比率,比如放到一个512*512的ImageView上,那么得出压缩比率是2, 即Options.inSimpleSize = 2,得出采样率,然后设置inJustDecodeBounds=false,根据Options的配置再次加载源图片,这个时候显示的就是512*512*4=1M的图片大小了,空间瞬间降了四倍。除了压缩,对图片进行缓存也是一个很好的优化,顺便说一句,google的Glide图片关键的加载配置是RGB565,即一个像素就是(5+6+5)=16bit =2byte,关键是图片几乎看不出失真现象,所以个人推荐使用Glide加载图片。
线程优化:线程优化的思想就是使用线程池,避免程序出现大量的线程,同时闲置的线程也能马上进入活跃状态,提高效率。Activity关闭的时候记得销毁。
优化建议:常量使用static final来修饰、不要过多的创建新对象,能复用最好、不要过多的使用枚举,枚举占用空间比整型大、适当使用弱引用和软引用、采用内存缓存和磁盘缓存、尽量采用静态的内部类(静态内部类相当于外部类一个静态变量,避免因为内部类持有外部类对象导致的内存泄漏)。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值