Android性能优化 浅析

来源:互联网 发布:苏州远洋数据有限公司 编辑:程序博客网 时间:2024/05/21 22:38

    Android App开发除了NDK之外,使用的都是Java语言,而Java语言是一种基于虚拟机JVM运行的语言,所以相比C/C++语言来说,效率是比较低的。Java需要占用大量内存来换取执行速度,而不定期的GC机制,直接导致Android界面的卡顿现象。

      相比Apple的iOS,Android要面对无数不同的硬件组合,分辨率,驱动等,导致App质量参差不齐。

      性能优化,简而言之,就是提高我们程序的性能,让我们的应用更快,更少使用CPU资源,更少使用内存。

      本文从以下几个方面浅谈一下Android的性能优化问题:


一、Java语言优化


1. 使用非阻塞I/O

      版本较低的JDK不支持非阻塞I/O API。为了避免I/O阻塞,一些应用采用了创建大量线程的方法(在较好的情况下,会使用一个缓冲池)。这种技术可以在许多必须支持并发I/O流的应用中见到,如web服务器等。然而,创建Java线程需要相当可观的开销。Java在JDK 1.4及以后版本中提供了一套API来专门操作非阻塞I/O,我们可以再java.nio包及其子包中找到相关的类和接口。由于这套API是JDK新提供的I/O API,因此,也叫New I/O,这就是包名nio的由来。这套API由3个主要的部分组成:缓冲区(Buffers)、通道(Channels)和非阻塞I/O的核心类。


2.慎用异常

     异常对性能不利。抛出异常首先要创建一个新的对象。Throwable接口的构造函数调用名为fillnStackTrace()的本地(Native)方法,fillnStackTrace()方法检查堆栈,收集调用跟踪信息。只要有异常被抛出,VM就必须调整调用堆栈,因为在处理过程中创建了一个新的对象。异常只能用于错误处理,不应该用来控制程序流程。


3. 变量和修饰符

      不要重复初始化变量,默认情况下,调用类的构造函数时,Java会把变量初始化成确定的值:所有的对象被设置成null,整数变量(byte、short、int、long)设置成0,float和double设置成0.0,逻辑值设置成false。所有尽量不要重复初始化变量。

      尽量使用局部变量,调用方法时传递的参数以及在调用中创建的临时变量都保存在栈(stack)中,速度较快,并且随所在线程的死亡而自动销毁。其他变量,如静态变量、实例变量等,都在堆(heap)中创建,速度较慢,垃圾回收是的耗能会导致APP出现卡顿现象。

      尽量指定类的final修饰符。带有final修饰符的类是不可派生的。另外,如果指定一个类为final,则该类所有的方法都是final。Java编译器会寻找机会内联(inline)所有的final方法。此举能够使性能平均提高50%。

      私有内部类要访问外部类的field或方法时,其成员变量不要用private,因为在编译时会生成setter/getter影响性能。可以把外部类的field或者方法声明为包访问权限。

       如果方法用不到成员变量,可以把方法申明为static,性能会提高到15%到20%。


4.其他方面:

     用位操作代替乘除法;

     用StringBuilder代替拼接操作;

     有算法进行复杂度的改进(必要的时候可以空间换时间);

     合理利用浮点数,浮点数比整形慢两倍。

     网络优化、异步线程、图片使用缓存等。


二、UI布局优化


1.   布局层数尽量少,RelativeLayout来代替LinearLayout因为RelativeLayout性能更优,且可以简单实现LinearLayout嵌套才能实现的布局


2.   采用<merge>标签优化合并布局层数:系统在编译XML布局文件时不会为<merge>生成任何节点,通过合并可以大大减少标签的生成。


3.   采用<include>标签共享重用其他布局:并用android:id属性覆盖被引用布局文件中顶层节点的android:id属性值,

[html] view plain copy
 print?
  1. <!—引用mylayout.xml文件>  
  2. <include android:id=”@+id/layout1” layout=”@layout/mylayout”/>  

4.   <viewstub>标签:viewstub标签同include标签一样可以用来引入一个外部布局,不同的是,viewstub引入的布局默认不会扩张,即既不会占用显示也不会占用位置,从而在解析layout时节省cpu和内存。

     viewstub常用来引入那些默认不会显示,只在特殊情况下显示的布局,如进度布局、网络失败显示的刷新布局、信息出错出现的提示布局等。


5.   通过Android SDK中tools目录下的layoutopt命令查看你的布局是否需要优化。


6.   将Activity中的window的背景图设置为空.getWindow().setBackgroundDrawable(null);android默认的背景不为空。


7.   View中设置缓存属性.setDrawingCache为true。动态加载View时采用ViewStub避免一些不经常的视图长期握住引用。


8.   采用SurfaceView在子线程刷新UI,避免手势的处理和绘制在同一UI线程(普通View都这样做)。


9.   ListView的优化

      item尽可能的减少使用的控件和布局的层次; RelativeLayout是绝对的利器,通过它可以减少布局的层次。同时要尽可能的复用控件,这样可以减少 ListView的内存使用,减少滑动时GC次数。ListView的背景色与cacheColorHint设置相同颜色,可以提高滑动时的渲染性能。 ListView中getView是性能是关键,这里要尽可能的优化。getView方法中要重用view;getView方法中不能做复杂的逻辑计算, 特别是数据库操作,否则会严重影响滑动时的性能。


三、数据库优化


1.    有些能用文件操作的,尽量使用文件操作,文件操作的速度比数据库的操作要快10倍左右。


2.    Cursor的使用,管理好cursor,不要每次打开关闭cursor,因为打开关闭cursor非常耗时。Cursor.require用于刷cursor。同时由于SQLiteDatabase对象较为耗费资源,所以我们在使用完SQLiteDatabase对象之后,必须立即关闭它,避免它继续占用资源,否则我们继续程序可能会导致OOM或者其他异常。


3.    SQLite使用事务,也可以自定义事务

[html] view plain copy
 print?
  1. Db.beginTransaction();  
  2. Db.setTransactionSuccessful();  
  3. Db.end Transaction();  

使用事务好处是原子提交和更优性能。


4.    可以建立索引,增加检索的速度。当某字段数据更新频率较低,查询频率较高,经常有范围查询(>,<, =, >=, <=)orderbygroup by发生时建议使用索引; 经常同时存取多列,且每列都含有重复值可考虑建立复合索引)。


5.    批量插入、更新使用原子操作,采用事务等方式。


6.    查询时返回更少的结果集及更少的字段。


7.    少cursor.getColumnIndex(可以在建表的时候用static变量记住某列的index,直接调用相应index而不是每次查询。)


8.    优化sql语句字符串等,语句的拼接使用StringBuilder代替String


四、新机制或者借用工具


1.    采用JNI技术,将耗时间的处理放到c/c++层处理。适当的采用NDK编程可以提高效率,但是内存回收不稳定,所以说适当。


2.    懒加载和缓存机制:访问网络的耗时操作启动一个新线程来做,而不要在UI线程做。还有从网络上获取大量图片的时候,可以本地缓存,下次获取同样图片的时候,可以先从本地获取,本地无再从网络获取。


3.    通过Android SDK中tools目录下的layoutopt命令查看你的布局是否需要优化;hierarchy viewer可以方便的查看Activity的布局,各个View的属性、measure、layout、draw的时间,如果耗时较多会用红色标记,否则显示绿色;利用android自带的性能跟踪工具TraceView查看跟踪函数调用,跟踪方法跟踪各部分的执行效率。


4.    可以在方法执行前后各使用system.currentTimeMillis方法获取当前系统的时间(毫秒),两个时间之差可以计算出方法的执行时间,进而可以改进优化。


5.    获取系统的内存信息

[html] view plain copy
 print?
  1. //获取系统内存总数  
  2. Long total = Runtime.getRuntime().totalMemory();  
  3. //获取剩余内存  
  4. Long free = Runtime.getRuntime().freeMemory();  
  5. //获取已经使用内存  
  6. Long used = total – free。  


引用参考:

http://www.trinea.cn/android/performance/(非常好的文章)
http://rayleeya.iteye.com/blog/1961005

http://developer.android.com/training/articles/perf-tips.html  (java)

http://rayleeya.iteye.com/blog/1961005 (java)

http://www.trinea.cn/android/java-android-performance/  (java)

http://blog.csdn.net/innost/article/details/9008691  (Traceview)

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 半永久眼线不掉怎么办 移植9天来月经怎么办 月经迟迟不来该怎么办 lol晋级赛输了怎么办 激素正常的多囊怎么办 右侧输卵管通而不畅怎么办 小该咳嗽老不好怎么办 孩子吓着了怎么办最快 2个月宝宝吓到了怎么办 3个月宝宝吓到了怎么办 宝宝吓着了发烧怎么办 好几个月不遗精怎么办 孕妇吃了黑橄榄怎么办 内膜4mm来月经了怎么办 吃了伟哥没效果怎么办 维a酸乳膏副作用怎么办 颈椎病引起的头晕恶心怎么办 经常头疼怎么办最快最有效 感昌了头晕乏力怎么办 来例假喝啤酒了怎么办 来月经喝啤酒了怎么办 吃的油腻长痘怎么办 兔子拉黑色稀便怎么办 宝宝补钙便秘了怎么办 吃了肾宝片上火怎么办 吃肾宝片就上火怎么办 吃肾宝片后上火怎么办 孕妇吃了扁桃仁怎么办 怀孕吃了扁桃仁怎么办 经期吃了阿胶糕怎么办 10儿童咳嗽有痰怎么办 6岁宝宝咳嗽有痰怎么办 儿童6岁咳嗽有痰怎么办 零号胶囊用多了怎么办 7岁半乳房发育,怎么办 妊娠斑怎么办,能去掉吗 跨域访问被拒绝怎么办 月子里半夜饿了怎么办 5岁儿童包茎该怎么办 6岁儿童包茎该怎么办 1岁半乳房发育,怎么办