android 应用性能优化

时间:2021-01-18 20:47:54

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 应用性能优化
代码动态或者版本android.os.Build工具类提供相应的静态方法
android 应用性能优化

如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语法的低效