使用注解@IntDef替代枚举学习

使用注解@IntDef替代枚举的实践

最近公司要求开一个新的项目,于是整理了原有项目的依赖库,升级最新的依赖,替换后的一个类库 BaseRecyclerViewAdapterHelper 在上拉加载更多的时候总是会多次调用 onLoadMoreRequested() 方法,处于好奇阅读了源码

 adapter.setOnLoadMoreListener(new BaseQuickAdapter.RequestLoadMoreListener() {
            @Override public void onLoadMoreRequested() {
                adapter.setEnableLoadMore(false);
                rvLoadmore.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        /*if (mCurrentCounter >= TOTAL_COUNTER) {
                            //数据全部加载完毕
                            mQuickAdapter.loadMoreEnd();
                        } else {
                            if (isErr) {*/
                                //成功获取更多数据
                        LogUtil.e("加载更多中....");


                        handler.sendEmptyMessageDelayed(200, 800);

                    }

                }, 50);
            }
        });
  • 至于上上面的代码调用多次的原因,本帖不做讨论。
  • 不过这一次的代码阅读让我受益匪浅,发现了一个好东西 @IntDef 赶紧贴一下代码。

     //Animation
        /**
         * Use with {@link #openLoadAnimation}
         */
        public static final int ALPHAIN = 0x00000001;
        /**
         * Use with {@link #openLoadAnimation}
         */
        public static final int SCALEIN = 0x00000002;
        /**
         * Use with {@link #openLoadAnimation}
         */
        public static final int SLIDEIN_BOTTOM = 0x00000003;
        /**
         * Use with {@link #openLoadAnimation}
         */
        public static final int SLIDEIN_LEFT = 0x00000004;
    
    
    
      @IntDef({ALPHAIN, SCALEIN, SLIDEIN_BOTTOM, SLIDEIN_LEFT, SLIDEIN_RIGHT})、
    
      @Retention(RetentionPolicy.SOURCE)
      public @interface AnimationType {
        }
    
    
    /**
     * Set the view animation type.
     *
     * @param animationType One of {@link #ALPHAIN}, {@link #SCALEIN}, {@link #SLIDEIN_BOTTOM},
     *                      {@link #SLIDEIN_LEFT}, {@link #SLIDEIN_RIGHT}.
     */
    public void openLoadAnimation(@AnimationType int animationType) {
        this.mOpenAnimationEnable = true;
        mCustomAnimation = null;
        switch (animationType) {
            case ALPHAIN:
                mSelectAnimation = new AlphaInAnimation();
                break;
            case SCALEIN:
                mSelectAnimation = new ScaleInAnimation();
                break;
            case SLIDEIN_BOTTOM:
                mSelectAnimation = new SlideInBottomAnimation();
                break;
            case SLIDEIN_LEFT:
                mSelectAnimation = new SlideInLeftAnimation();
                break;
            case SLIDEIN_RIGHT:
                mSelectAnimation = new SlideInRightAnimation();
                break;
            default:
                break;
        }
    }
    

开始研究(下面就深扒一下具体的使用)

讲真的 @IntDef 第一次见,赶紧的百度,忽然间发现真是个不错的东西。

百度 Android 官方文档找到下面的说明

Be careful with code abstractions
Developers often use abstractions simply as a good programming practice, because
abstractions can improve code flexibility and maintenance. However, abstractions
come at a significant cost: generally they require a fair amount more code that
needs to be executed, requiring more time and more RAM for that code to be mapped
into memory. So if your abstractions aren’t supplying a significant benefit, you
should avoid them.

For example, enums often require more than twice as much memory as static constants. You should strictly avoid using enums on Android.

大体的意思就是: 我们在写代码的时候要注意类型的使用,以便于提高代码的扩展性和维护性,但是原型的使用一般会付出更多的内存的代价,所以如果没有特别大的好处,要尽量避免使用。对于枚举来说占用的内存往往是使用静态常量的两倍,因而我们要尽量避免在Android中使用枚举 。
http://developer.android.com/training/articles/memory.html#Overhead

  • 可以看出Android 官方还是比较推荐使用 @IntDef 来代替枚举的使用的
  • 下面咱们就学习一下怎么使用吧!

  • 1.首先,添加android注解依赖:

    compile 'com.android.support:support-annotations:25.1.0'
    
  • 2.使用

    public class StatusDialog extends Dialog{
    
          //常量定义
          public static final int STATE_NONE = -1;
          public static final int STATE_LOADING = 0;
          public static final int STATE_SUCCESS = 1;
          public static final int STATE_ERROR = 2;
          public static final int STATE_EMPTY = 3;
    
          //限定state的取值必须是构造器常量中的一个
          private @State int state;
    
          //在声明函数的同时限定函数参数的取值,将其写在需要限定的参数前
          public void setState(@State int state){
              this.state = state;
          } 
    
          @State
          public int getState() {
            return this.state;
          }
    
          //用 @IntDef "包住" 常量;  
          // @Retention 定义策略  
          // 声明构造器  
          @IntDef({STATE_EMPTY, STATE_ERROR, STATE_LOADING, STATE_NONE, STATE_SUCCESS})
          @Retention(RetentionPolicy.SOURCE)
          public @interface State {
          }
    
      }
    

好了到这里我们就可以放心的使用了

  • 到这里我们研究一下 Retention声明的构造器的保留级别 参考 http://blog.csdn.net/u011315960/article/details/64918467

    • 1、SOURCE:在原文件中有效,被编译器丢弃。
    • 2、CLASS:在class文件有效,可能会被虚拟机忽略。
    • 3、RUNTIME:在运行时有效。

猜你喜欢

转载自blog.csdn.net/bencheng06/article/details/78756350
今日推荐