Android开发中的性能优化---代码

  这篇主要总结一些优化代码的技巧,一些写代码中的小细节,可能就会影响程序的执行效率,比如一个地方只会影响1ms,那么1000个地方就会影响1s,1s到底长不长?要知道Activity出现ANR异常的时间为5s!!! 
  主要遵循两个原则 
  1.不要创建一些没必要创建的对象以及重复定义某个变量 
  对象的创建是一个非常繁琐的步骤,JVM首先会对通过new指令对符号进行解析,以此来判断该类是否被加载,然后在堆中进行内存分配,为对象分配完内存空间后,就会对内存区域进行初始化(该为0的为0,该为null的为null,这也是为什么方法中的变量需要程序员显示初始化),最后JVM会调用对象的构造函数,而且一般都会有一个变量建立该对象的引用。 
  所以,创建对象是很麻烦的,就不要没事干就创建对象了。 
   
  2.用完的对象要及时回收 
  就是常说的GC,这里要明确的是,什么时候进行GC操作,不是由程序员决定的,JVM会在有必要的时候自行启动GC,程序员只能做到建议JVM尽快对某对象进行GC,它有两个评判标准 
  (1) 该对象失去引用,那么最好的办法就是将不用的对象赋值为null 
  (2) 该对象离开作用域,比如说方法执行完毕,局部变量和对象就会被回收,所以尽可能少生命全局变量。 
  并且GC操作也是要耗内存的@[email protected]! 
  

开始

1.最频繁的 + 和 +“” 操作

  Java中的 +号既可以进行数值计算,又可以进行字符串操作,但是在进行字符串操作的时候,它是一种效率很低的方式,虽然用起来非常非常方便!

1.1 不要直接使用 +号 进行字符串拼接

  开发中使用“+”号运算符的确非常方便,但是效率也非常低,因为“+”号内部实际上调用的是StringBufferappend()方法,然后再转换成String,那么它肯定没有直接调用快。 
  还有一个就是StringBuilder,这个类是Java1.5时出来的,从效率上来说,它和StringBuffer区别在于StringBuilder不是线程安全的,多线程操作会出现问题,那么就比较容易选择了, 
  在单线程中,使用StringBuilder,在多线程中使用StringBuffer

1.2 不要直接使用 +“” 来进行字符串转化

  将对象转化成字符串的操作有三种,效率从快到慢依次是,xxx.toStringString.valueOf(xxx)、 xxx +"" 
  xxx.toString是直接转化,而String.valueOf(xxx)底层是调用了toString()方法,至于+"",在1.1时已经说了,它会先转化成SringBuffer,然后再调用toString(),所以结果一目了然

上述两点可以看下面的代码

通过javap -c 的指令, 能够看到下面的内容, 虽然左边的不一定能看懂, 但是右边的注释很容易理解

2.循环的使用细节(以for为例)

  循环是开发中频率出现很高的一种操作,它的作用就是简化重复的步骤,比如说添加10000条数据到某个集合中,如果不用循环,即使复制粘贴也要好久,但是通过循环操作就可以几行代码完成。但这里面就会容易出现一些小的细节,有可能就会影响程序的执行效率。以下代码举例:

1 List<String> list = new ArrayList<>();
2 for (int i = 0; i < 100; i++) {
3     Random random = new Random();
4     Integer result = random.nextInt(100);
5     String s = result.toString();
6     list.add(s);
7 }    

2.1 尽量不要在循环中创建不必要的对象

  示例代码中在for循环中创建了100个Random对象,而实际进行随机数操作的是该对象的nextInt()方法,那么实际上可以写成:

  

List<String> list = new ArrayList<>();
// 对象创建在for循环外
Random random = new Random();
for (int i = 0; i < 100; i++) {
    Integer result = random.nextInt(100);
    String s = result.toString();
    list.add(s);
}

2.2 不用的对象要及时回收

  这里只是举个例子,实际开发中有可能出现的情况是,解析一段Json,然后获取到了Json中的某个对象并添加到了集合中,那么这个被解析过的对象其实就没什么用了,因为数据已经添加到了集合中,比较我们要用的是数据而不是对象,此时就可以置为null,让JVM尽快的回收掉它,这是一个非常好的习惯,

  但有些时候例外, 面这种情况, 将对象置为null, 但实际上该对象的引用仍然被list集合所持有, 所以对象不会被回收掉

  

 1 List<String> list = new ArrayList<>();
 2 Random random = new Random();
 3 Integer result;
 4 String s;
 5 for (int i = 0; i < 100; i++) {
 6     result = random.nextInt(100);
 7     s = result.toString();
 8     list.add(s);
 9     result = null;  // 此时虽然将对象置为null, 但是它的引用依然是被list所持有的, 即使result置为null, 仍然不会来回收
10     s = null;
11 }

  比较好的做法应该是清空list集合然后将list置为null

1 list.clear();  // 要先将list所持有的对象给清空掉
2 if(list != null) {
3     list = null;
4 }

在实际开发中, 可以写在onDestory()方法中

2.4 适当的建立方法结果的缓存

  比如有时候为了简便会这样写 
   
   
   
  Java在调用某个方法时,其实也不是那么简单,要创建栈帧来存储局部变量表,操作数栈,动态连接,方法返回地址,还要方法调用现场、恢复方法调用现场等一系列操作。所以,如果list的size()非常大时,也会影响效率,所以可以定义一个变量而不是直接使用 
   
  

3. if和switch的使用

  既然有了循环,那么就应当有判断@[email protected]!

3.1 通过if来在合适的时候创建对象或调用方法

  这个也算一个小细节 
   
   
  这个循环里面可以看出,只有在随机数为20的时候集合才会添加该数据,所以在此之前,将随机数调用toString()方法毫无意义。所以可以写为 
  

4 使用位运算来代替乘除运算

  计算机只懂二进制,而位运算就是直接的二进制运算,所以当然效率比较高,

  当然也有缺点 
    (1) 对于数字过大,还是直接乘除比较方便 
    (2) 代码的可读性不高

5 合理利用Activity的生命周期

  Activity的生命周期最常用的莫过于onCreate(),但是其它的生命周期我想也很有必要恰当的利用。 
   
   
  这个仅仅是个人书写习惯,不知道会不会影响到性能,但是最起码这样写代码结构比较清晰 :)

6 使用Zipalign来进行代码对齐

  Zipalign是一个SDK下的工具,能够对apk文件中未压缩的数据在4个字节边界上对齐,当资源文件通过内存映射对齐到4字节边界时,android系统就可以通过调用mmap函数读取文件, 
  mmap函数是Linux系统的调用函数,提供了不同于一般对普通文件的访问方式,进程可以像读写内存一样对普通文件的操作,进程可以像读写内存一样对普通文件的操作,不必再read()和write(),在读取资源上获得较高的性能。如果资源本身没有进行对齐处理,它就必须显式地读取它们——这个过程将会比较缓慢且会花费额外的内存。 
  具体用法我会在工具篇中总结

7 使用SparseArray代替HashMap  使用SparseArray来代替HashMap,原因是一次Android Studio的提示,

   
   
  使用SparseArrayHashMap好,所以就网上查找了些SparseArray的一些相关资料 
  简单的来讲,SparseArray适用于HashMap<Integer, Object>这样的结构,因为SparseArray内部是用的int型数组存储keyObject型的数组存储value的值,省去了int包装成Integer的过程. 
   
   
  根据这篇文章,可以看出来,在数据过多时,效率上SparseArray并没有比HashMap更快,但是该文章作者结尾处说内存的使用状况上,能够节约27% 
  
   
  而这篇文章的作者专门对内存的使用状况做了测试,说是内存上优化了35% 
   
  
  我通过Android Studio自带的工具观察内存消耗,使用HashMap大约在3.24~3.31 
   
  
  而SparseArray大约在3.0~3.1之间 
   
  
    不过具体优化了多少不是重点,反正是对内存开销上SparseArray开销更低更具有优势~! 
 另外除了SparseArray,ArrayMap,SparseBoolMap,SparseIntMap,SparseLongMap,LongSparseMap等等一些列API,在内存使用方面都相对于HashMap要好的多

8 I/O流尽量使用带Buffer的

  带Buffer缓冲区的I/O对象效率要比不带的高一些,

9. 能不static就不static,能final就final

  static虽然让成员用起来很爽,但是会延长它们的生命周期 
  final会使对象无法被继承,变量无法被修改,方法无法被重写,并且会进行内联

结束

  暂时想到的就这么多了,仅仅是一些开发中的细节部分,有些众所周知的就没写,比如复用ListViewConvertView,压缩图片、异步加载等等,

原文地址:https://www.cnblogs.com/sweep/p/8419217.html

时间: 2024-11-03 21:56:55

Android开发中的性能优化---代码的相关文章

Android开发中的性能优化---布局

1.基础 Android中所有的View都是"画"在手机屏幕上的,系统是每隔16ms更新一次Activity中的内容,所以为了让用户看不到卡顿,就要想尽一切方法来让界面在16ms内更改完成,遵循的原则其实只有一个-----尽量的少画东西,这样效率当然就会提高,至于什么减少布局层次,避免重复绘制,总结下来还是尽量少画东西.    为什么是16ms?因为现在市面上的手机一般都是60hz的,所以 16ms/ 帧 ≈ 1s / 60hz 2.方法 使用手机中的开发人员工具--->调试GP

如何在Android开发中让你的代码更有效率

如何在Android开发中让你的代码更有效率 最近看了一个视频,名字叫做Doing More With Less: Being a Good Android Citizen,主要是讲如何用少少的几句代码来改善Android App的性能.在这个视频里面,演讲者以一个图片app为例讲解如何应用Android中现有的东西来改善app性能问题. 这个图片app的代码:https://github.com/penkzhou/iogallery.ppt:http://greenrobot.qiniudn.

使用ThinkPHP开发中MySQL性能优化的最佳21条经验

使用ThinkPHP开发中MySQL性能优化的最佳21条经验讲解,目前,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要担心的事,而这更是我 们程序员需要去关注的事情.当我们去设计数据库表结构,对操作数据库时(尤其是查表时的SQL语句),我们都需要注意数据操作的性能.这里,我们不会讲过 多的SQL语句的优化,而只是针对MySQL这一Web应用最多的数据库.希望下面的这些优化技巧对你有用. 1. 为查询缓存优化你的查询大多数的MySQ

Android开发中的SQLite优化

关于SQLite的优化,首先是能用SQL语句批次处理的,就不要单笔操作,Cursor就更是能不用就不用.比如成批的DELETE/UPDATE,将条件组装到SQL语句,会比使用CURSOR一条条的查再删效率要高很多(若干年前就曾使用存储过程代替单笔操作,将一次批量计算时间从一天缩到了数分钟以内,参考).其次是对操作的优化:对于INSERT/UPDATE操作较多时使用事务,如果SELECT操作较多时,使用索引. 结合现在的工作,发现针对操作的优化,下面这篇文章可以翻译出来归档.以下为正文: SQLi

由浅入深讲解android开发中listview的性能优化

ListView是一种可以显示一系列项目并能进行滚动显示的View.在每行里,既可以是简单的文本,也可以是复杂的结构.一般情况下,你都需要保证ListView运行得很好(即:渲染更快,滚动流畅).在接下来的内容里,我将就ListView的使用,向大家提供几种解决不同性能问题的解决方案. 如果你想使用ListView,你就不得不使用ListAdapter来显示内容.SDK中,已经有了几种简单实现的Adapter: ·         ArrayAdapter<T> (显示数组对象,使用toStr

那些Android中的性能优化

性能优化是一个大的范畴,如果有人问你在Android中如何做性能优化的,也许都不知道从哪开始说起. 首先要明白的是,为什么我们的App需要优化,最显而易见的时刻:用户say,什么狗屎,刷这么久都没反应,取关卸载算了. 这跟什么有关,我们先苍白的反驳下,尼玛用户设备老旧网又烂,关我屁事,根本不用优化.可是,老板拍板了,施压给CTO,然后CTO又来找你:Y的今天必须给我想办法优化了,不然不准回家. 好吧,为什么从UI的表象上看,App又卡又慢而且还错乱.我们试着来剖析下吧. 题外话:把minSDK改

android app 开发过程中 对于性能优化的总结

一款手机应用  从开发过程中就要做好 性能优化,这样才能 让用户体验度 提升, 假如 我们打开一个应用 出现卡顿, 不流畅,则会很影响 用户对该应用的态度,产品狗 都很注意这些人机交互方面的 体验. 谷歌官方也是一直在优化 android 系统,不论是  碎片化处理 还是 系能 上面,这方面 ios 就做的比较好,配置比 android 低,但是流畅度却比android高,体验效果更好. 官方推荐方案:http://www.oschina.net/news/60157/android-perfo

Android开发中常用的ListView列表的优化方式ViewHolder

在Android开发中难免会遇到大量的数据加载到ListView中进行显示, 然后其中最重要的数据传递桥梁Adapter适配器是常用的,随着市场的需 求变化ListView'条目中的内容是越来越多这就需要程序员来自定义适配器, 而关键的就是适配器的优化问题,适配器没有优化好往往就会造成OOM (内存溢出)或者是滑动卡顿之类的问题,接下来我就给大家介绍一种常 用的Adapter优化方法 1 /** 2 * list View的适配器 3 */ 4 class Adapter extends Bas

android开发中图片优化步骤

android开发中图片优化方法 1.图片加载方法,方便用户加载图片 /*** * 加载本地图片 * @param context:主运行函数实例 * @param bitAdress:图片地址,一般指向R下的drawable目录 * @return */ public final Bitmap CreatImage(Context context, int bitAdress) { Bitmap bitmaptemp = null; bitmaptemp = BitmapFactory.dec