优化Android程序:
1.1 优化java代码:
① 尽量使用static和final修饰符:相比于其他方法,调用静态方法的效率是最高的。final有着“无法改变”的意思,还可以保护数据和逻辑;
② 尽量使用局部变量:局部变量是保存在栈中的,这要比保存在堆(Heap)中的代价要小,并且调用效率更高;
③ 不要过度依赖GC:如果在短时间内大量的创建对象,可能会导致oom。常见的回收方式是在使用之后,将其手动设置为null;
④ 优化循环代码:首先应该避免重复的计算;
⑤ 慎用异常机制:异常的捕捉代价很大;
⑥ 基本数字运算:
a) 运行速度顺序:int,short,byte,long,float和double;
b) 除法比乘法慢太多,基本上除法是乘法运算时间的9倍;
c) long类型计算很慢,需要少用;
d) double运算速度和float相当。
⑦ 字符串操作使用StringBuffer,应该尽量避免使用+操作拼接字符串;
⑧ 合理使用数据集合:
a) java集合数据:
i. 集合结构Collection
1. List:有序的Collection
a) LinkedList:双向链表:可以用于实现栈、队列、双向队列
b) ArrayList:高级数组:可变大小的数组
c) Vector:线程安全
i. Stack
2. Set
ii. 图标结构Map
1. Hashtable:线程安全
2. HashMap:
3. WeakHashmap:
集合的功能虽然十分强大,但是性能却远远比不上原生的数据结构
⑨ 使用clone代替new;使用clone不会调用任何的构造方法。
⑩ 慎用public static final:
a) 变量这样声明就无法再做任何更改,这种数组也无法进行增、删、改以及排序的操作;
b) 这样声明的数据,在整个进程被销毁之前会常驻内存,会引起性能问题;
11 采用对象池提高效率:比如线程池,数据库链接池。
12 不要过度使用oop思想:有的时候比较简单的逻辑可以直接使用基本数据类型代替。
1.2 异步获取数据:
① Handler+Message+Looper
② AsyncTask
1.3文件资源缓存:
① SDCard的缓存策略是:利用图片url做为图片的唯一Id,然后异步获取到图片资源后将其缓存到SD卡中;
1.4数据库缓存:
① 对于文本数据一般采用数据库缓存,因为这样可以方便的进行增、删、改、查操作。
避免内存泄露:
2.1 Android内存管理:
Android使用的是不遵循java虚拟机规范的Davlik 虚拟机,与传统Java SE的区别如下:
l Davlik虚拟机更接近Linux内核,支持多线程;
l Davlik虚拟机基于寄存器,与传统的基于栈的Java虚拟机不同;
l Davlik虚拟机使用自己的字节码(.dex文件),不兼容传统的Java字节码格式;
l Davlik虚拟机的常量池只使用32位的索引,以简化解释器;
l Davlik虚拟机默认栈的大小事12KB(3页,每页4KB);
l Davlik虚拟机默认堆启动大小是2MB,最大为16MB(该值与设备有关,也有24MB、48MB的);
每个安卓应用的内存大小是有限制的(一般为16MB);
2.2 如何判断内存泄露:
MAT内存分析工具:
a. 安装:
a) 在Eclipse中的Help=》Install New Software=》MAT - http://download.eclipse.org/mat/1.4/update-site/
b. 使用:
a) 在DDMS中选定一个device,并且指定到一个运行中的app,接着点击按钮:Update Heap=》随后点击几次Cause gc:手动清理几次内存,内存泄露的地方不会被清理掉,最后将会分析这些没被清理掉的内存
b) 最后点击Dump HPROF file,进行内存分析;
2.3 常见内存泄露的处理:
出现内存溢出的根本原因是程序引用了某些对象,但是却从来没有使用过,致使GC无法正常回收,最终导致了内存泄露问题。
1.程序逻辑的内存泄露:
a) 避免循环引用的出现。A类引用B类的对象,B类中又引用A类的对象。
2.数据库查询没有关闭游标:
3.合理使用上下文:
a) 最常见的Context造成内存泄露是因为超出自身的生命周期而导致的。(Service中引用Activity的Context),推荐使用Application Context;
b) Activity类内使用静态声明的时候要特别注意,比如控件最好不要声明成静态的,而内部类最好是静态的。
4.Bitmap使用之后未调用recycle方法释放内存;
5.构造Adapter时未使用缓存的View对象;
优化Android UI:
3.1模板代码优化:
① 不要使用固定的绝对定位布局(absolutelyLayout);
② 不要使用px,统一使用pd或者pid,如果是文本,则使用sp;
③ 所有的资源都要针对高分辨率屏幕创建(缩小比放大好);
④ 使用适当的间距(margin,padding)
⑤ 适当处理屏幕的方向,必要的时候要固定频幕的方向;
⑥ 使用主题和样式来减少界面的冗余。
3.2 布局优化:
1.使用合适的布局方式:根据样式,选择合适的布局,尽量使布局格式最简洁。
2.学会复用模板资源:
复用模板资源要用到<merge><include>标签;
3.使用Hierarch Viewer工具:
在SDK的tools目录中:hierarchviewer.bat
4.使用layoutopt.bat工具:
在SDK的tools目录中:layoutopt.bat 后面要接上xml文件的完整路径
(现在已经改名为lint.bat)
5.学会直接用java语言构造UI界面,因为解析xml布局还是很耗资源的,如果直接用java编写出布局,将会提高性能。
其他优化:
4.1优化图片:
① 图片压缩策略:减少图片的颜色、色深可以减少图片的大小(比如减少色深一半,可以使图片的大小减少三分之一)
② 压缩工具(PNGOUT):采用图片压缩工具,可以使图片变小,但是显示效果依旧;
4.2优化APK包:
4.3 使用keytoo 和jarsigner签名
① 对APK包安装签名的主要原因:
a) 签名过程会对包中每个文件都进行处理,进而生成唯一的key,并以此保证每个安装包信息的完整性。另外,签名不同的包不可以被覆盖安装,因此签名过的包是安全的。
b) 发送者的身份认证,防止交易中的抵赖情况:
② 对原始的APK包进行签名的具体步骤:
a) 准备工作:C:\Users\Administrator>jarsigner -verify C:\Users\Administrator\Desktop\YiGuanJia.apk:验证apk签名情况;
b) 使用keytool生成公私钥和证书: C:\Users\Administrator\Documents\androidkey>keytool -genkey -keyalg RSA -validity 365 -alias luichi -keypass 123456 -keystore yiguanjia.key -storepass 123456 -dname "CN=luichi,OU=,O=,L=nj,ST=js,C=cn"
可以使用:C:\Users\Administrator\Documents\androidkey>keytool -list -v -keystore yiguanjia.key -storepass 123456验证key的内容有没有错误。
c) 使用jarsinger进行签名
C:\Users\Administrator\Documents\androidkey>jarsigner -verbose -keystore yiguanjia.key -signedjar YiGuanJia-signed.apk YiGuanJia.apk luichi 并对签名过后的APK,重新命名为YiGuanJia-signed.apk;
d) 验证签名是否成功
4.4 使用zipalign优化:(使资源访问更有效率)
此工具在现在的tools中已经没有,可以把 sdk\build-tools\android-4.4W\ 文件夹下 的 zipalign.exe 拷贝到 sdk\tools\ 文件夹下,即可。
命令:
D:\tools\adt-bundle-windows\sdk\tools>zipalign -v 4 YiGuanJia-signed.apk YiGuanJ
ia-final.apk
Verifying alignment of YiGuanJia-final.apk (4)...
..................................(过程省略)
Verification succesful
这样就可以生成一个最终签名并且zipalign之后的apk包。