当前位置 主页 > 网站技术 > 代码类 >

    Android使用注解代替枚举节省系统内存开销的方法

    栏目:代码类 时间:2020-01-31 15:06

    Java5以后开始支持枚举类型,枚举类型使用起来非常方便,其重要的作用是作为类型安全使用的。如果在不考虑系统内存开销的情况下大量的使用枚举也不会有什么问题。但是移动端还是需要注意的。

    android系统在应用启动后会给应用单独分配一块内存。应用的dex code、heap以及运行时的内存分配都会在这块内存中。而使用枚举类型的dex size是普通常亮的13倍以上。在运行时的内存分配,一个enum的声明至少要消耗掉20个bytes。从这两点就可以说明,在app中大量使用枚举的内存开销是非常大的。

    枚举最大的优势是类型安全。那么是不是又办法在不使用枚举的情况下做到类型安全呢?答案是肯定的,下面看看怎么干。

    goodle官方很早就发现了枚举对android系统带来的性能开销,所以在其官网上就已经提醒了开发者尽量少的使用枚举,而且还提供了注解的方式来检查类型安全。目前其提供了int和string两种注解方式。分别是:IntDef和StringDef。

    话不多说,直接上例子。ps:demo里面有详细的注释。

    一、Int类型注解检查类型安全

    package com.yw.enumproxylib;
    
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    
    import androidx.annotation.IntDef;
    
    /**
     * 定义一个int类型的注解
     * 用注解代替枚举,做到类型安全
     * create by yangwei
     * on 2020-01-30 21:34
     */
    public class EnumProxy {
      public static final int READ_CAR = 0;//红色的汽车
      public static final int GREEN_CAR = 1;//绿色的汽车
      public static final int YELLOW_CAR = 2;//黄色的汽车
    
    
      @IntDef({READ_CAR, GREEN_CAR, YELLOW_CAR})
      @Retention(RetentionPolicy.SOURCE)//源码级别
      public @interface CAR_Enum {
    
      }
    
      /**
       * 获取汽车类型
       *
       * @param car
       * @return
       */
      public static int getCar(@CAR_Enum int car) {
        switch (car) {
          case READ_CAR:
            return 0;
          case GREEN_CAR:
            return 1;
          case YELLOW_CAR:
            return 2;
        }
        return -1;
      }
    }

    二、String类型注解检查类型安全

    package com.yw.enumproxylib;
    
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    
    import androidx.annotation.StringDef;
    
    /**
     * 定义一个string类型的注解,用于检查星期的类型安全。
     * create by yangwei
     * on 2020-01-30 22:04 week
     */
    public class StringEnum {
    
      public static final String MONDAY = "monday";
      public static final String TUESDAY = "tuesday";
      public static final String WENDESDAY = "wendesday";
      public static final String THURSDAY = "thursday";
      public static final String FRIDAY = "friday";
      public static final String SATURDAY = "saturday";
      public static final String WEEKDAY = "weekday";
    
      @StringDef({MONDAY, TUESDAY, WENDESDAY, THURSDAY, FRIDAY, SATURDAY, WEEKDAY})//此处定义注解的值只能是这几个
      @Retention(RetentionPolicy.SOURCE)//编译时注解,源码级检查
      public @interface Week {
    
      }
    
      /**
       * 获取日期
       *
       * @param week
       * @return
       */
      public static String getWeek(@Week String week) {
        switch (week) {
          case MONDAY:
            return "星期一";
          case TUESDAY:
            return "星期二";
          case WENDESDAY:
            return "星期三";
          case THURSDAY:
            return "星期四";
          case FRIDAY:
            return "星期五";
          case SATURDAY:
            return "星期六";
          case WEEKDAY:
            return "星期日";
        }
        return null;
      }
    }