Android的Java代码优化

在深入开发之前,你应该意识到代码优化不是应用开发的首要任务。提供良好的用户体验并专注于代码的可维护性才是首要任务。


1.Android如何执行代码

我们需要分清楚:最终Android应用只包含Dalvik字节码,而不是Java字节码。

APK文件只是简单的ZIP压缩文件,可以用常见的压缩工具解压。

Dalvik虚拟机是基于寄存器(虚拟寄存器,非真实的硬件寄存器),Sun的java虚拟机JVM是基于栈。

Java指令是16位的,JVM和DEX指令集基本也是16位。

Android2.2中引入了实时编译器(JIT)。Dalvik JIT编译器把Dalvik字节码编译成本地代码,这样可以明显加快执行速度。

在应用的manifest配置里可以用Android:vmSafeMode启用或禁用JIT编译器。默认是启动。


2.Java算法优化

Java所有基本类型中(除了boolean),long是64位,int32位,short是16位。所有整数类型都是有符号的。

BigInteger对象可以容纳任意大小的有符号整数,这是解决很多数值超过64位后的一种解决方案。

基于性能方面的考虑,在代码的关键路径上要尽可能避免内存分配。

优化往往使源代码难于阅读、理解和维护。强烈建议你先实现一个能运行的解决方案,然后再考虑优化。有一句高德纳的名言:“过早的优化是噩梦之源”

Java语言规范说了两件事:A、Error类及其子类是普通程序中抛出的异常,它通常是不期望能够恢复的。B、精密的程序可能希望抓住这类异常并试图从错误异常中恢复。

与直觉相反,并非所有异常都是Exception的子类。所有异常都是Throwable的子类(只有Exception和Error是它的直接子类)。

3.缓存结果

Android定义了SparseArray类,当键值是整数时,效率比HashMap高。

android.util.LruCache这个3.1版本后的缓存工具类。还是建议自己写一个LRU。

API等级,试图调用不存在的API将导致崩溃。可以用反射来检查是否存在SDK_INT字段(是否高于1.6版本)。不过反射会使代码变慢,因此,在性能至关重要的地方应尽量避免使用反射。替代的办法是在静态初始化块里调用Class.forName(),Class.getMethod()确认制定方法是否存在,在性能要求搞的地方只调用Method.invoke()即可。

指定maxSdkVersion可能导致Android更新后,应用自动被卸载,所以不建议指定max sdk version。

Android Market使用minSdkVersion和maxSdkVersion属性来筛选可供特定设备下载安装的应用,其它属性也同样可以用来筛选。

4.响应能力

在Android基础组件中的onSomething()方法都是由主线程(UI线程)调用。主线程主要处理:按键事件(onKeyDown等)、绘制View(onDraw)和调用生命周期(onCreate等)。应用只有一个主线程,所有的事件都按顺序处理。

展开资源是一个开销相对较大的操作,所以尽量降低布局的复杂性。几个降低布局复杂性的步骤:A、使用RelativeLayout代替LinearLayout,尽可能“扁平化”设计布局。此外,减少创建的对象数量。B、使用ViewStub推迟对象创建。

优化的基本原则是保持应用的持续响应,让主线程尽可能快得完成任务。

写程序时,应该始终假定两种情况:A、网络很慢。B、文件系统访问速度很慢。结论就是不应该在主线程内进行网络操作或者访问文件系统。

StrictMode是检测不良行为的工具。注意:只在开发阶段启用StrictMode,发布应用时,记得禁用。


5.SQLite

SQLite语句、事务和查询。SQLite语句创建时,使用StringBuffer对象(推荐使用)或调用String.format可以提高性能。

SQLite内部有虚拟机,处理字节码指令。使用compileStatement让语句在循环外只编译一次。

显示创建事务有以下两个基本特性:原子提交和性能更好。一次性事务是解决批量或数据库在持久存储中的较好方法。

查询时,只读取需要的数据才是上上之选。


以上内容是《Android应用性能优化》第一章节的读后整理。如需要了解详细内容或者深入学习,请查看此书。后续读后感请继续关注本博客:

http://blog.csdn.net/forlong401



原文地址:https://www.cnblogs.com/bbsno1/p/3253807.html