使用注解@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:在运行时有效。