安卓代码优化(3)

1、避免创建短命的临时对象。
减少对象的创建就能减少垃圾收集,进而减少对用户体验的影响。
案例:
(1)截取一段字符串时,尽量使用substring函数取得原始数据的一个子串,而不是为子串另外建立一份拷贝。
(2)多维数组分成多个一维数组
(3)int数组比Integer数组好,这也概括了一个基本事实,两个平行的int数组比 (int,int)对象数组性能要好很多

2、静态方法:
如果不需要访问某对象的字段,将方法设置为静态,调用会加速15%到20%。

3、 避免内部Getters/Setters
在公共接口中使用Getters和Setters是有道理的,
但在一个字段经常被访问的类中宜采用直接访问。
无JIT时,直接字段访问大约比调用getter访问快3倍。有JIT(编译器)时(直接访问字段开销等同于局部变量访问),要快7倍。

4、将成员缓存到本地

(1)访问成员变量比访问本地变量慢得多
一般代码:直接访问成员变量

for(int i =0; i <this.mCount; i++)  {
   dumpItem(this.mItems);
}

//改成访问本地变量:更快

//////转为本地变量:
int count = this.mCount;
Item[] items = this.mItems;

for(int i =0; i < count; i++)  {
       dumpItems(items);
}

(2)永远不要在for的第二个条件中调用任何方法:

for(int i =0; i < this.getCount(); i++) {}

(3)、同样如果你要多次访问一个变量,也最好先为它建立一个本地变量(方法的参数和本地变量一样)
一般的代码:

protected void drawHorizontalScrollBar(Canvas canvas, int width, int height) {
if(isHorizontalScrollBarEnabled()) {

intsize = mScrollBar.getSize(false);
if(size <=0) {
       size = mScrollBarSize;
}

mScrollBar.setBounds(0, height - size, width, height);

mScrollBar.setParams(computeHorizontalScrollRange(), computeHorizontalScrollOffset(), computeHorizontalScrollExtent(),false);
mScrollBar.draw(canvas);
}
}

//分析:
mScrollBar在方法中使用了四次,可以将他转换为本地变量!

5、 对常量使用static final修饰符
案例:
static int intVal = 42;
在编译过程中:
必以其会生成一个叫做clinit的初始化类的方法,当类第一次被使用的时候这个方法会被执行。方法会将42赋给intVal;
/改进:加上final:
—->
类不再需要clinit方法,因为在成员变量初始化的时候,会将常量直接保存到类文件中;
//分析:
将一个方法或类声明为final不会带来性能的提升,
但是会帮助编译器优化代码。

举例说,如果编译器知道一个getter方法不会被重载,那么编译器会对其采用内联调用。

5、改进的for循环语 法和迭代器具有相同的效率
在其他集合类中:
迭代器让接口调用 hasNext()和next()方法。在ArrayList中,手写的计数循环迭代要快3倍(无论有没有JIT)
for展示集中访问数组:

static class Foo {
        int mSplat;
    }
    Foo[] mArray = ...
    //每次循环都会访问两次静态成员变量,取得一次数组的长度。
    public void zero() {
        int sum = 0;
        for (int i = 0; i < mArray.length; ++i) {
            sum += mArray[i].mSplat;
        }
    }
//将所有成员变量存储到本地变量
    public void one() {
        int sum = 0;
        Foo[] localArray = mArray;
        int len = localArray.length;
        for (int i = 0; i < len; ++i) {
            sum += localArray[i].mSplat;
        }
    }
//每次执行时会给a进行赋值
    public void two() {
        int sum = 0;
        for (Foo a : mArray) {
            sum += a.mSplat;
        }
}
}

6、 避免使用浮点数

7、了解并使用类库
选择Library中的代码而非自己重写,除了通常的那些原因外,
考虑到系统空闲时会用汇编代码调用来替代library方法;
涉及到的场景:(c、c++实现的)

(1)String.indexOf(),String.lastIndexOf()等特殊实现的方法、System.arraycopy比循环快多了!

(2) android.text.format包下的Formatter类,
提供了IP地址转换、文件大小转换等方法;
DateFormat类,提供了各种时间转换,都是非常高效的方法

(3)、系统的TextUtils类
字符串处理Android为我们提供了一个简单实用的TextUtils类

(4)、高性能MemoryFile类
实现高性能的文件读写操作
/分析:
对于I/O需要频繁操作的,主要是和外部存储相关的I/O操作,MemoryFile通过将 NAND或SD卡上的文件,分段映射到内存中进行修改处理

8、合理利用本地方法
当你分配本地资源时 (本地堆上的内存,文件说明符等),往往很难实时的回收这些资源。
9、复杂算法尽量用C完成
复杂算法尽量用C或者C++完成,然后用JNI调用;

10、减少不必要的全局变量
尽量避免static成员变量引用资源耗费过多的实例,比如Context。

Android提供了很健全的消息传递机制(Intent)和任务模型(Handler),可以通过传递或事件的方式,防止一些不必要的全局变量。

11、资源的回收,不用过多指望gc:
Java的gc使用的是一个有向图,判断一个对象是否有效看的是其他的对象能到达这个对象的顶点
显示让系统回收:

if(bitmap.isRecycled()==false) { //如果没有回收
     bitmap.recycle();
}

12、了解Java四种引用方式
强引用、软引用、弱引用和虚引用

13、使用实体类比接口好
//接口
Map map1 = new HashMap();
//接口
HashMap map2 = new HashMap();

14、避免使用枚举:
枚举变量非常方便,但不幸的是它会牺牲执行的速度和并大幅增加文件体积public class Foo {
public enum Shrubbery { GROUND, CRAWLING, HANGING }
}

/改进:
使用ordinal()方法获取枚举变量的整数值会更好一些:

int valX = MyEnum.VAL_X.ordinal();
int valY = MyEnum.VAL_Y.ordinal();
int count = list.size();
MyItem items = list.items();
for(int n =0; n < count; n++) {
       intvalItem = items[n].e.ordinal();
       if(valItem == valX) {
              // do something
       } else if(valItem == valY) {
              // do something
       }
}

15、在私有内部内中,考虑用包访问权限替代私有访问权限

public class Foo {
           public class Inner {
                public void stuff() {
                       Foo.this.doStuff(Foo.this.mValue);
                }
           }
           private int mValue;
           public void run() {
                Inner in = new Inner();
                mValue = 27;
                in.stuff();
           }
           private void doStuff(int value) {
                 System.out.println("value:"+value);
           }
}

//分析:
可以通过声明被内部类访问的字段和成员为包访问权限,而非私有。但这也意味着这些字段会被其他处于同一个包中的类访问,因此在公共API中不宜采用。

16、适量使用缓存:
17、关闭资源对象:
对SQLiteOpenHelper,SQLiteDatabase,Cursor,文件,I/O操作等都应该记得显示关闭。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值