android 性能优化小技巧

好的性能离不开好的代码,这里不讲大的oo原则,只讲一些基本的小技巧。
 
1.尽量使用static 
 
static 能够使 变量,方法 变为属于类的,访问时能够节省访问对象的时间。能够快15%-20%的时间。
 
2,对于 基本类型变量或String类型变量,如果内容不变的话,尽量使用 static final
 
使用 static final 能够进一步提高效率,
 
static int intVal = 42;
static String strVal = "Hello, world!";
当第一次使用类中的static变量时, 虚拟机会调用 <clinit> 方法去初始化类,并将 42 保存到 iniVal 变量中, 将 字符串内容保存到 字符串常量表中,并将引用赋值给 strVal。
当访问时,需要执行一次变量访问操作。
 
而使用 static fianl的话
static final int intVal = 42;
static final String strVal = "Hello, world!";
当访问时,不需要初始化类,访问 intVal时,会直接使用 42, 访问 strVal 时, 会使用一个相对来说效率更高的字符串访问指令。都比static 变量访问快很多。
 
 
3,遍历数组,或Collection<E> (ArrayList 除外)时,使用  for-each循环 要比 传统的 for(int i = 0 ; i< length ; ++i) 要更好。但是对于ArrayList , 传统的for 循环效率更高。
 
4,引用正确的类型比引用接口效率高??
对于没有 JIT 的设备, 的确如此。 但是对于 拥有 JIT 的设备来说,两种方式效率方面没啥差别,主要是JIT做了相关方面的优化。
 
这里提到了 JIT , 就简单说一下什么是 JIT。    
====================摘自 百度百科=========
 
JIT Compiler(Just-in-time Compiler) 即时编译。
最早的 Java建置方案是由一套转译程式(interpreter),将每个Java指令都转译成对等的微处理器指令,并根据转译后的指令先后次序依序执行,由于一个Java指令可能被转译成十几或数十几个对等的微处理器指令,这种模式执行的速度相当缓慢。 
针对这个问题,业界首先开发出JIT(just in time)编译器。当Java执行runtime环境时,每遇到一个新的类别(class:类别是Java程式中的功能群组),类别是Java程式中的功能群组-JIT编译器在此时就会针对这个类别进行编译(compile)作业。经过编译后的程式,被优化成相当精简的原生型指令码(native code),这种程式的执行速度相当快。花费少许的编译时间来节省稍后相当长的执行时间,JIT这种设计的确增加不少效率。
但是它并未达到最顶尖的效能,因为某些极少执行到的Java指令在编译时所额外花费的时间可能比转译器在执行时的时间还长,针对这些指令而言,整体花费的时间并没有减少。 基于对JIT的经验,业界发展出动态编译器(dynamic compiler),动态编译器仅针对较常被执行的程式码进行编译,其余部分仍使用转译程式来执行。也就是说,动态编译器会研判是否要编译每个类别。动态编译器拥有两项利器:一是转译器,另一则是JIT,它透过智慧机制针对每个类别进行分析,然后决定使用这两种利器的哪一种来达到最佳化的效果。动态编译器针对程式的特性或者是让程式执行几个循环,再根据结果决定是否编译这段程式码。这个决定不见得绝对正确,但从统计数字来看,这个判断的机制正确的机会相当高。事实上,动态编译器会根据「历史资料」做决策,所以程式执行的时间愈长,判断正确的机率就愈高。以整个结果来看,动态编译器产生的程式码执行的速度超越以前的JIT技术,平均速度可提高至50%。 
============================================
Android原来Dalvik虚拟机是作为一种解释器实现,从2.2开始,新版将换成JIT编译器实现。
JIT 在性能方面做了很多优化,很多代码编写方面能够提高效率的小技巧 都不需要用了,它就帮你搞定了。
 
上面说的这些对程序的整体性能方面其实影响不大,主要是为了写出更好的代码,积少成多嘛。
 
 
设计篇
1.缓存
一些经常要访问的东西可以考虑缓存起来。
网络的资源可以考虑缓存到硬盘。
减少网络访问次数,节省流量,加快显示速度。但是需要考虑硬盘大小的问题。
如果不考虑占用硬盘空间问题,那就简单了,直接存到硬盘。
但是有一些软件,如有大量图片需要缓存到硬盘,如果长期使用,可能会把sd卡撑爆。这样可以考虑使用一个指定最大大小的硬盘cache,当达到最大大小时,删除老的资源。
具体可以参考 http://developer.android.com/shareables/training/BitmapFun.zip
里面有一个类 DiskLruCache  ,非常好的实现了一个可以指定最大大小的硬盘缓存类。
 
硬盘里的可以考虑缓存到内存。
减少硬盘访问,加快速度。
可以使用android提供的 LruCache 类来帮我们。
 
例如图片缓存。
当有很多小图片需要重复显示时,可以考虑将图片缓存到内存中,减少对硬盘的访问,减少创建Bitmap 的次数,来优化性能。这个尤其是在ListView , GridView 显示小图片时,能够显著提高性能。
我们可以使用LruCache 类来帮助我们达成目的。可以创建一个给定缓存大小的LruCache 实例,当访问图片时,先到缓存中找,如果有就直接用,如果没有,就创建图片,然后将图片添加到缓存中。
LruCache 构造方法需要传递缓存最大的大小作为参数,然后向缓存中添加图片的时候,如果剩余缓存空间已经放不下新的图片,它就删除最老的图片。什么是最老的?它以添加时间以及最近使用时间做参考,时间最早的就是最老的。
 
 
代码如下
 
 
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
public enum ImageCache { 
   
     INSTANCE; 
   
     public static final String TAG = "ImageCache"
   
     private static final float defaultCacheSizePercent = 1 .0f / 10
   
     private LruCache<String, BitmapDrawable> mMemoryCache; 
     private int memCacheSize; 
   
     ImageCache() { 
         memCacheSize = Math.round(defaultCacheSizePercent 
                 * Runtime.getRuntime().maxMemory() / 1024 ); //采用虚拟机最大内存的十分之一作为缓存大小。使用kb作为单位,这里的单位只要与sizeof方法返回的单位保持一致就行。 
     mMemoryCache = new LruCache<String, BitmapDrawable>(memCacheSize) { 
                 @Override 
                 protected int sizeOf(String key, BitmapDrawable value) { 
                 return getBitmapSize(value); //获得图片大小。这个用作管理缓存大小的依据 。 
            
   
         }; 
   
    
   
     /**
      * Get the size in bytes of a bitmap in a BitmapDrawable.
     
      * @param value
      * @return size in bytes
      */ 
     @TargetApi ( 12
     public static int getBitmapSize(BitmapDrawable value) { 
         int size = 0
         Bitmap bitmap = value.getBitmap(); 
   
         if (<span style= "font-family: Arial, Helvetica, sans-serif;" >Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1</span>) { 
             size =  bitmap.getByteCount(); 
        
         // Pre HC-MR1 
         size =  bitmap.getRowBytes() * bitmap.getHeight(); 
         return size == 0 ? 1 : size / 1024
    
   
     /**
      * Adds a bitmap to both memory and disk cache.
     
      * @param data
      *            Unique identifier for the bitmap to store
      * @param value
      *            The bitmap drawable to store
      */ 
     public void addBitmapToCache(String data, BitmapDrawable value) { 
         if (data == null || value == null ) { 
             return
        
   
         // Add to memory cache 
         if (mMemoryCache != null ) { 
             mMemoryCache.put(data, value); 
        
   
         if (Log.isLoggable(TAG, Log.DEBUG)) { 
             Log.i(TAG, "add to Memory cache :" + data); 
        
   
    
   
     /**
      * Get from memory cache.
     
      * @param data
      *            Unique identifier for which item to get
      * @return The bitmap drawable if found in cache, null otherwise
      */ 
     public BitmapDrawable getBitmapFromMemCache(String data) { 
         BitmapDrawable memValue = null
   
         if (mMemoryCache != null ) { 
             memValue = mMemoryCache.get(data); 
   
        
   
         if (Log.isLoggable(TAG, Log.INFO)){ 
             Log.i(TAG, mMemoryCache.toString()); 
        
   
         return memValue; 
    
   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值