Android使用枚举正确姿态

作者: WilsonMing | 来源:发表于2017-06-19 17:06 被阅读329次

    那实际开发中肯定是要用Java枚举的,那有没有什么解决办法了。答案肯定是有的,只是换成另外一种方式

    /**
    * Android枚举
    */
    public class TestEnum {
      /**
       * @Retention(RetentionPolicy.SOURCE) 注解可以告知编译器不将枚举的注解数据存储在 .class 文件中
       *
       */
      /**
       * @StringDef创建整型和字符串集的枚举注解来验证其他类型的代码引用
       * 具体详细看官网{@link https://developer.android.com/studio/write/annotations.html?hl=zh-cn#adding-annotations}
       */
      @Retention(RetentionPolicy.SOURCE)
      @StringDef({
              POWER_SERVICE,
              WINDOW_SERVICE,
              LAYOUT_INFLATER_SERVICE
      })
      //@interface这是Java用来定义一个注解类。
      public @interface ServiceName {}
      public static final String POWER_SERVICE = "power";
      public static final String WINDOW_SERVICE = "window";
      public static final String LAYOUT_INFLATER_SERVICE = "layout_inflater";
      public static String getSystemService(@ServiceName String name) {
          if (POWER_SERVICE.equals(name)) {
              return POWER_SERVICE;
          } else if (WINDOW_SERVICE.equals(name)) {
              return WINDOW_SERVICE;
          } else if (LAYOUT_INFLATER_SERVICE.equals(name)) {
              return LAYOUT_INFLATER_SERVICE;
          }
          return null;
      }
      public static void main(String[] args) {
          //使用
    System.out.println(TestEnum.getSystemService(TestEnum.LAYOUT_INFLATER_SERVICE));
      }
    }
    

    这就是官网的写法了。可是发现每次传参数是

    TestEnum.LAYOUT_INFLATER_SERVICE
    或者
    TestEnum.POWER_SERVICE
    

    而不是像我们Java枚举的传参方式

    ServiceName.LAYOUT_INFLATER_SERVICE
    

    那是不是需要改造下。查看资料可以这样写

    /**
     * Android枚举
     */
    public class TestEnum {
        /**
         * @Retention(RetentionPolicy.SOURCE) 注解可以告知编译器不将枚举的注解数据存储在 .class 文件中
         *
         */
        /**
         * @StringDef创建整型和字符串集的枚举注解来验证其他类型的代码引用 具体详细看官网{@link https://developer.android.com/studio/write/annotations.html?hl=zh-cn#adding-annotations}
         */
        @Retention(RetentionPolicy.SOURCE)
        @StringDef({
                ServiceName.POWER_SERVICE,
                ServiceName.WINDOW_SERVICE,
                ServiceName.LAYOUT_INFLATER_SERVICE
        })
        //@interface这是Java用来定义一个注解类。
        public @interface ServiceName {
            String POWER_SERVICE = "power";
            String WINDOW_SERVICE = "window";
            String LAYOUT_INFLATER_SERVICE = "layout_inflater";
        }
    
        public static String getSystemService(@ServiceName String name) {
            if (ServiceName.POWER_SERVICE.equals(name)) {
                return ServiceName.POWER_SERVICE;
            } else if (ServiceName.WINDOW_SERVICE.equals(name)) {
                return ServiceName.WINDOW_SERVICE;
            } else if (ServiceName.LAYOUT_INFLATER_SERVICE.equals(name)) {
                return ServiceName.LAYOUT_INFLATER_SERVICE;
            }
            return null;
        }
    
        public static void main(String[] args) {
            //使用
            System.out.println(TestEnum.getSystemService(ServiceName.LAYOUT_INFLATER_SERVICE));
        }
    }
    

    不错,就是把常量放到里面去了。这个时候差不多好了,不过怎么看

    public static String getSystemService(@ServiceName String name) {
            if (ServiceName.POWER_SERVICE.equals(name)) {
                return ServiceName.POWER_SERVICE;
            } else if (ServiceName.WINDOW_SERVICE.equals(name)) {
                return ServiceName.WINDOW_SERVICE;
            } else if (ServiceName.LAYOUT_INFLATER_SERVICE.equals(name)) {
                return ServiceName.LAYOUT_INFLATER_SERVICE;
            }
            return null;
        }
    

    这个代码还是有点怪怪的,每次添加一个值都需要加一个else if太麻烦了。在Java中可以通过enum.values()获取所有enum的值那是不是有类似的方法,找了资料好像没有发现,那只能通过反射获取所有的public的参数和参数值了

    public static String getSystemService(@ServiceName String name) {
            Field[] fields = ServiceName.class.getDeclaredFields();
            for (Field field : fields) {
                //在反射对象中设置 accessible 标志允许具有足够特权的复杂应用程序(比如 Java Object Serialization 或其他持久性机制)以某种通常禁止使用的方式来操作对象
                field.setAccessible(true);
                String value = null;
                try {
                    value = String.valueOf(field.get(field.getName()));
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                if (value != null && value.equals(name)) {
                    return value;
                }
            }
            return null;
        }
    

    ok完成,代码地址

    这里有几个知识点参考资料链接

    相关文章

      网友评论

        本文标题:Android使用枚举正确姿态

        本文链接:https://www.haomeiwen.com/subject/ntfnqxtx.html