性能优化在安卓开发中是个重要的话题,那么究竟怎么来优化我们的App呢?
下面是针对谷歌给的建议加入了一些个人想法的结果:
一、内存优化
1.限制service的使用,后台任务使用IntentService.
2.隐藏UI时释放内存,例如网络连接、注销广播
3.当内存紧张时释放部分内存,
在所有ui组件不可见时会回调onTrimMemory方法,根据内存级别决定释放内存,当然onTrimMemory
是在API14(安卓4.0)被加进来的,所以要对老版本兼容的话使用onLowMemory回调方法
4.检查你应该使用多少的内存
不同设备为App提供了不同大小的内存限制,可以通过getMemoryClass获取可用heap大小,单位是兆字节
5.避免bitmaps浪费内存,如对原图分辨率高于设备分辨率的做缩放处理
6.使用优化的数据集合,例如使用SparseArray代替HashMap
7.避免使用枚举,Enums的内存消耗通常是静态常量的2倍
8.谨慎使用抽象,这里一般在考虑好灵活性和维护性的基础上,尽量避开使用,比如
直接使用ArrayList<T> list = new ArrayList<T>();而不是List<T> list = new ArrayList<T>();
但实际上是在使用JIT设备上没多大差异,JIT是安卓2.2版本加入的。
9.为序列化的数据使用nano protobufs,这里我们平常使用Json数据格式比较多,使用Json即可
10.避免使用依赖注入框架
11.谨慎使用第三方库,它不一定针对移动环境优化过
12.使用ProGuard映射混淆代码,可以对代码进行压缩
13.对开发完成的APK使用zipalign
14.使用多进程,对于后台操作时,前台的UI资源没法释放,可以分成两个进程,在manifest文件里
声明android:process属性
二、代码优化
1.避免创建不必要的对象
2.独立的方法选择static,比如工具类
3.常量声明为static final
4.避免内部的Getters/Setters
5.使用增强的For循环写法
6.内部类访问外部类成员变量考虑使用包级修饰来代替private访问修饰,但是公开的API中不要这么做
7.避免使用float数据类型
8.使用系统封装好的API而不是自己重写,就是有现成的API就最好不要自己写
9.谨慎使用native函数,JNI开销也是比较大的
10.使用traceview测量性能,但是测量的数据没有经过JIT优化,实际效果比测试出来的数据是要稍微好些的
三、布局优化
(1)优化layout层级
检查你的布局
尽量避免过多的布局控件嵌套,层级不要太深
可以使用hierarchyviewer这个工具查看布局
使用Lint检查可以优化的地方,AndroidStudio会自动运行Lint检查
(2)使用<include><merge>标签重用layouts
(3)使用ViewStub按需加载视图
(4)优化ListView
耗时任务使用后台线程
使用View Holder来保存需要使用的视图
四、电量优化
(1)监测电池的电量与充电状态,充电时增加操作量,低电量时减少操作量
(2)判断并监测设备的停驻状态与类型,如充电状态,车载模式
(3)判断并监测网络连接状态
1)判断当前是否有网络连接
显然如果没有网络连接,那么就没有必要做那些需要联网的事情
2)判断连接网络的类型
根据网络的带宽做适合的事情
3)监测网络连接的切换
比如在有Wi-Fi的时候进行下载,若是网络切换到移动网络则通常会暂停当前下载,监听
到恢复到Wi-Fi的情况则开始恢复下载
(4)按需操控广播接收者,不用时注销广播接收者
五、其他优化
(1)使用多线程,多线程使用线程池,使用Handler与UI通信
(2)避免ANR,耗时任务使用异步处理,UI上显示加载进度
(3)使用JNI,但是JNI需要开销,要视具体情况和需求而定
(4)优化多核处理器,多线程操作避免读取共享数据出错
下面是针对谷歌给的建议加入了一些个人想法的结果:
一、内存优化
1.限制service的使用,后台任务使用IntentService.
2.隐藏UI时释放内存,例如网络连接、注销广播
3.当内存紧张时释放部分内存,
在所有ui组件不可见时会回调onTrimMemory方法,根据内存级别决定释放内存,当然onTrimMemory
是在API14(安卓4.0)被加进来的,所以要对老版本兼容的话使用onLowMemory回调方法
4.检查你应该使用多少的内存
不同设备为App提供了不同大小的内存限制,可以通过getMemoryClass获取可用heap大小,单位是兆字节
5.避免bitmaps浪费内存,如对原图分辨率高于设备分辨率的做缩放处理
6.使用优化的数据集合,例如使用SparseArray代替HashMap
7.避免使用枚举,Enums的内存消耗通常是静态常量的2倍
8.谨慎使用抽象,这里一般在考虑好灵活性和维护性的基础上,尽量避开使用,比如
直接使用ArrayList<T> list = new ArrayList<T>();而不是List<T> list = new ArrayList<T>();
但实际上是在使用JIT设备上没多大差异,JIT是安卓2.2版本加入的。
9.为序列化的数据使用nano protobufs,这里我们平常使用Json数据格式比较多,使用Json即可
10.避免使用依赖注入框架
11.谨慎使用第三方库,它不一定针对移动环境优化过
12.使用ProGuard映射混淆代码,可以对代码进行压缩
13.对开发完成的APK使用zipalign
14.使用多进程,对于后台操作时,前台的UI资源没法释放,可以分成两个进程,在manifest文件里
声明android:process属性
二、代码优化
1.避免创建不必要的对象
2.独立的方法选择static,比如工具类
3.常量声明为static final
4.避免内部的Getters/Setters
5.使用增强的For循环写法
6.内部类访问外部类成员变量考虑使用包级修饰来代替private访问修饰,但是公开的API中不要这么做
7.避免使用float数据类型
8.使用系统封装好的API而不是自己重写,就是有现成的API就最好不要自己写
9.谨慎使用native函数,JNI开销也是比较大的
10.使用traceview测量性能,但是测量的数据没有经过JIT优化,实际效果比测试出来的数据是要稍微好些的
三、布局优化
(1)优化layout层级
检查你的布局
尽量避免过多的布局控件嵌套,层级不要太深
可以使用hierarchyviewer这个工具查看布局
使用Lint检查可以优化的地方,AndroidStudio会自动运行Lint检查
(2)使用<include><merge>标签重用layouts
(3)使用ViewStub按需加载视图
(4)优化ListView
耗时任务使用后台线程
使用View Holder来保存需要使用的视图
四、电量优化
(1)监测电池的电量与充电状态,充电时增加操作量,低电量时减少操作量
(2)判断并监测设备的停驻状态与类型,如充电状态,车载模式
(3)判断并监测网络连接状态
1)判断当前是否有网络连接
显然如果没有网络连接,那么就没有必要做那些需要联网的事情
2)判断连接网络的类型
根据网络的带宽做适合的事情
3)监测网络连接的切换
比如在有Wi-Fi的时候进行下载,若是网络切换到移动网络则通常会暂停当前下载,监听
到恢复到Wi-Fi的情况则开始恢复下载
(4)按需操控广播接收者,不用时注销广播接收者
五、其他优化
(1)使用多线程,多线程使用线程池,使用Handler与UI通信
(2)避免ANR,耗时任务使用异步处理,UI上显示加载进度
(3)使用JNI,但是JNI需要开销,要视具体情况和需求而定
(4)优化多核处理器,多线程操作避免读取共享数据出错