android 应用性能优化

本文介绍了几种Android开发中常用的性能优化方法,包括使用SparseIntArray替代HashMap提高内存效率,利用LruCache进行缓存管理,以及针对不同API等级进行代码适配等。还对比了String.format与StringBuilder的性能。

java.match.BigInteger 可以解决范围溢出的问题,但是开辟内存空间更大

android的FloatMath 更高效率的解决双精度的运算

当键是整数时,sparseArray比hashMap更加高效 理由;HashMap使用的是泛型,这时需要Integer 而SparseArray使用的是基本类型Int,不会创建很多Integer对象,因此SpareArray更省内存 在这里强调一点,以为java很拿手的同学,android一般都很烂,自信没问题,但是忽略的内存

实例:

  new Thread(new Runnable() {
                    @Override
                    public void run() {
                        int loopTimes = 1000;
                        long addStartTime1 = SystemClock.elapsedRealtime();
                        for (int i = 0; i < loopTimes; i++) {
                            testMap.put(i, i);
                        }
                        long addEndTime1 = SystemClock.elapsedRealtime();
                        LogUtils.d("------->hashMap add " + loopTimes + " items take time:" + (addEndTime1 - addStartTime1));
                        long addStartTime2 = SystemClock.elapsedRealtime();
                        for (int i = 0; i < loopTimes; i++) {
                            testArray.put(i, i);
                        }
                        long addEndTime2 = SystemClock.elapsedRealtime();
                        LogUtils.d("------->sparseIntArray add " + loopTimes + " items take time:" + (addEndTime2 - addStartTime2));
                    }
                }).start();

运行5次的结果:

09-06 02:05:16.152 3845-4010/com.xuan.study_project D/LogUtils: ------->hashMap add 1000 items take time:16
09-06 02:05:16.154 3845-4010/com.xuan.study_project D/LogUtils: ------->sparseIntArray add 1000 items take time:2
09-06 02:05:30.976 3845-4208/com.xuan.study_project D/LogUtils: ------->hashMap add 1000 items take time:1
09-06 02:05:30.977 3845-4208/com.xuan.study_project D/LogUtils: ------->sparseIntArray add 1000 items take time:0
09-06 02:05:32.248 3845-4226/com.xuan.study_project D/LogUtils: ------->hashMap add 1000 items take time:0
09-06 02:05:32.251 3845-4226/com.xuan.study_project D/LogUtils: ------->sparseIntArray add 1000 items take time:2
09-06 02:05:33.478 3845-4244/com.xuan.study_project D/LogUtils: ------->hashMap add 1000 items take time:2
09-06 02:05:33.479 3845-4244/com.xuan.study_project D/LogUtils: ------->sparseIntArray add 1000 items take time:0
09-06 02:05:40.726 3845-4341/com.xuan.study_project D/LogUtils: ------->hashMap add 1000 items take time:2
09-06 02:05:40.726 3845-4341/com.xuan.study_project D/LogUtils: ------->sparseIntArray add 1000 items take time:1

结论:SparseIntArray的性能比HashMap好,java程序员所熟悉的hashMap 大多数情况在android平台不适合

在android中定义了很多这样的稀疏数组:SparseArray(键为整数,值为对象) SparseBoolArray和SparseIntArray,非常快速和省内存


LruCache

android.util.LruCache<K,V> android 3.1提供的,可以在创建时定义缓存的最大长度,另外,还可以通过覆盖sizeof方法改变每个缓存条目计算大小的方式,
LRU (Least Recently Used)缓存先丢弃最近最少使用的项目,因此平台的限制,使得3.1之前需要用LinkedHashMap 然后复写removeEledestEntry,在这里,如果的程序要兼容那么老的版本,您应该分版本 3.1之上的用Lru 3.1之下用LinkedHashMap

API等级判断


代码动态或者版本android.os.Build工具类提供相应的静态方法


如NestdScolling是5.0上面 一般控件才有的特性,如果要禁用这个特性,需要判断版本号

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    itme_name_3.setNestedScrollingEnabled(false);
    item_more_3.setNestedScrollingEnabled(false);
}

Exception

Exception 通常不期望能够恢复的,如果并非所有得分异常都是Exception的子类,但所有异常都是Throwable的子类


strictMode 检查

strictMode 是android系统提供的不良行为检测工具
用法 在baseApplication中添加如下代码:
StrictMode.setThreadPolicy(
                    new StrictMode.ThreadPolicy.Builder()
                            .detectCustomSlowCalls()
                            .detectDiskReads()
                            .detectDiskWrites()
                            .detectNetwork()
                            .penaltyLog()
                            .penaltyFlashScreen()
                            .build()
            );
            try {
                //其实和性能无关,但如果使用strictMode 最好也定义一下VM策略
                StrictMode.setVmPolicy(
                        new StrictMode.VmPolicy.Builder()
                                .detectLeakedSqlLiteObjects()
                                .detectLeakedClosableObjects()
                                .setClassInstanceLimit(Class.forName("com.apress.proandroid.SomeClass"), 100)
                                .penaltyLog()
                                .build());
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }

运行程序:


String.format与StringBuilder 性能对比

在得到一个拼凑字符串的方式有很多,如++,format StringBuilder,接下来演示其速度
    public static class User {
        public int id;
        public String name;
        public int age;

        public User(String name, int age, int id) {
            this.name = name;
            this.age = age;
            this.id = id;
        }
    }
new Thread(new Runnable() {
                    @Override
                    public void run() {
                        int loopTimes = 1000;
                        //先模拟1000条数据
                        List<User> users = new ArrayList<User>();
                        for (int i = 0; i < loopTimes; i++) {
                            users.add(new User("name_" + i, new Random().nextInt(100), i));
                        }

                        long startTime1 = SystemClock.elapsedRealtime();
                        for (int i = 0; i < users.size(); i++) {
                            User user = users.get(i);
                            String userItem = String.format("id:%d name:%s age:%d", user.id, user.name, user.age);
                        }

                        long endTime1 = SystemClock.elapsedRealtime();
                        LogUtils.d("------->format: " + loopTimes + " items take time:" + (endTime1 - startTime1));
                        long startTime2 = SystemClock.elapsedRealtime();
                        for (int i = 0; i < users.size(); i++) {
                            User user = users.get(i);
                            StringBuilder stringBuilder = new StringBuilder();
                            stringBuilder.append("id");
                            stringBuilder.append(user.id);
                            stringBuilder.append("name");
                            stringBuilder.append(user.name);
                            stringBuilder.append("age");
                            stringBuilder.append(user.age);
                            String userItem = stringBuilder.toString();

                        }
                        long endTime2 = SystemClock.elapsedRealtime();
                        LogUtils.d("------->StringBuilder: " + loopTimes + " items take time:" + (endTime2 - startTime2));
                    }
                }).start();
运行结果:
09-06 04:51:34.420 20101-20216/com.xuan.study_project D/LogUtils: ------->format: 1000 items take time:48
09-06 04:51:34.435 20101-20216/com.xuan.study_project D/LogUtils: ------->StringBuilder: 1000 items take time:15
09-06 04:51:35.356 20101-20228/com.xuan.study_project D/LogUtils: ------->format: 1000 items take time:43
09-06 04:51:35.358 20101-20228/com.xuan.study_project D/LogUtils: ------->StringBuilder: 1000 items take time:2
09-06 04:51:36.057 20101-20240/com.xuan.study_project D/LogUtils: ------->format: 1000 items take time:40
09-06 04:51:36.059 20101-20240/com.xuan.study_project D/LogUtils: ------->StringBuilder: 1000 items take time:1
09-06 04:51:36.678 20101-20252/com.xuan.study_project D/LogUtils: ------->format: 1000 items take time:44
09-06 04:51:36.680 20101-20252/com.xuan.study_project D/LogUtils: ------->StringBuilder: 1000 items take time:2
09-06 04:51:37.345 20101-20265/com.xuan.study_project D/LogUtils: ------->format: 1000 items take time:84
09-06 04:51:37.346 20101-20265/com.xuan.study_project D/LogUtils: ------->StringBuilder: 1000 items take time:1

可以看到stringBuilder的性能远比format 主要场景有 sqlite 如
insert into user values(%d,$s,%d)
建议用stringBuilder

在android中在处理数据库这样的格式化操作有SqliteStateMent 如 bindString 也有ContentValues put(key,value) android系统对contentValue优化很多,建议使用这个类似的hashMap 
在sqlite的使用建议DatabaseUtils这个工具类,它里面的静态方法非常高效,避免了java语法的低效
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

亚洲小炫风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值