美文网首页
Android中使用注解替代枚举

Android中使用注解替代枚举

作者: 珊珊宝贝Catherine | 来源:发表于2018-05-08 10:23 被阅读26次

    枚举最大的作用是提供了类型安全。为了弥补Android平台不建议使用枚举的缺陷,官方推出了两个注解,IntDef和StringDef,用来提供编译期的类型检查。
    首先,引入依赖包:

    implementation 'com.android.support:support-annotations:27.1.0'
    

    定义一个注解

    public @interface TaskStatus {
    
    }
    

    是的,类似于接口的定义,加个 @ 符号。

    注解一般使用步骤

    那么对于上面的枚举和常量都不 work 的场景,如何使用枚举解决呢?

    1. 定义注解类,添加常量
    @Retention(RetentionPolicy.SOURCE)
    public @interface TaskStatus {
        int UN_KNOW = -1;
        int UN_START = 0;
        int PROGRESSING = 1;
        int COMPLETED = 2;
    }
    

    和接口成员一样,注解类的成员默认就是 public static final 修饰的。

    @Retention(RetentionPolicy.SOURCE) 表示告诉编译器,该注解是源代码级别的,生成 class 文件的时候这个注解就被编译器自动去掉了。

    doSth() 方法:

    public class TaskHelper {
    
        public static void doSth(@TaskStatus int status){
            switch (status){
                case TaskStatus.UN_KNOW:
                    //do something
                    break;
                case TaskStatus.UN_START:
                    break;
                case TaskStatus.PROGRESSING:
                    break;
                case TaskStatus.COMPLETED:
                    break;
            }
        }
    }
    

    可以看出,doSth() 方法的参数是 int 类型的,但是使用 @TaskStatus 进行了注解,这样外界就无法传递 TaskStatus之外的成员作为参数了。

    1. 调用
    TaskHelper.doSth(TaskStatus.UN_START);
    

    在调用时,IDE 会提示 @TaskStatus int status,提醒我们传入 TaskStatus 类型的值。

    同时,调用者如果再随便传入一个 int 值,虽然可以运行,但代码会爆红,lint 检查将会给与警告:

    Must be one of: TaskStatus.UN_KNOW, TaskStatus.UN_START, TaskStatus.PROGRESSING, TaskStatus.COMPLETED
    

    如此,保证了类型安全。但也只是警告,仍然可以运行,但总比没有警告强多了。

    补充

    其实这种用法在 Android 源码中屡见不鲜,比如 Resources 下的 getDrawable() 方法:

    public Drawable getDrawable(@DrawableRes int id) throws NotFoundException {
            final Drawable d = getDrawable(id, null);
            //...
            return d;
        }
    

    使用时,我们一般会这么用:

    getResources().getDrawable(R.drawable.ic_launcher);
    

    虽然是 int 值,但是当我们这么用时:

    getResources().getDrawable(111);
    

    就会爆红并提示:

    Expected resource of type drawable
    

    再补充一点,为了防止在我们定义的常量值重复,我们还可以使用Android 注解支持库(support-annotations)中的 @IntDef 来限定常量不允许重复:

    @IntDef({
            TaskStatus.UN_KNOW,
            TaskStatus.UN_START,
            TaskStatus.PROGRESSING,
            TaskStatus.COMPLETED
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface TaskStatus {
        int UN_KNOW = -1;
        int UN_START = 0;
        int PROGRESSING = 1;
        int COMPLETED = 2;
    }
    

    相关文章

      网友评论

          本文标题:Android中使用注解替代枚举

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