ADTT #1 — Put It Inside @IntDef

Or @StringDef, whichever you use…

I’ve been avoiding Enums in Android since forever. Even Android docs clearly states (as of May 1st) that we should strictly avoid enums when developing in Android.

Watch the video by Colt McAnlis to find out why enums is so bad in Android:

To replace enums, I’ve been using @IntDef and @StringDef. And I’m pretty sure you have been creating some too, or at least use the one that Android Framework provides: @Visibility

// Inside View.java
public static final int VISIBLE = 0x00000000;
public static final int INVISIBLE = 0x00000004;
public static final int GONE = 0x00000008;
@IntDef({VISIBLE, INVISIBLE, GONE})
@Retention(RetentionPolicy.SOURCE)
public @interface Visibility {}
// Our class
view.setVisibility(View.GONE);

I usually create a single java file, say Constant.java, to contains all those definitions.

int FAILURE = 0;
int SUCCESS = 1;
@IntDef(value = {FAILURE, SUCCESS})
@Retention(RetentionPolicy.SOURCE)
public @interface ResponseStatus {}
int SINGLE = 0;
int RANGE = 1;
@IntDef(value = {SINGLE, RANGE})
@Retention(RetentionPolicy.SOURCE)
public @interface PickerType {}

But as the application grows, there are more types to maintain. And there’s also possibility that two options having the same name but different functionality. For example MaritalStatus with options SINGLE/MARRIED/DIVORCED. Obviously SINGLE in MaritalStatus is different than SINGLE in PickerType, so I won’t mix them up together.

I could add prefix to each of the options so that it becomes PICKER_TYPE_SINGLE and MARITAL_STATUS_SINGLE but that’s just messy IMO. All those variables sitting together unseparated. Is there a better solution?

Luckily yes, I’ve been putting the possible values of @IntDef and @StringDef inside the @interface definition.

@IntDef(value = {ResponseStatus.FAILURE, ResponseStatus.SUCCESS})
@Retention(RetentionPolicy.SOURCE)
public @interface ResponseStatus {
int FAILURE = 0;
int SUCCESS = 1;

}
@StringDef(value = {PickerType.SINGLE, PickerType.RANGE})
@Retention(RetentionPolicy.SOURCE)
public @interface PickerType {
int SINGLE = 0;
int RANGE = 1;
}
@StringDef(value = {MaritalStatus.SINGLE, MaritalStatus.MARRIED, MaritalStatus.DIVORCED})
@Retention(RetentionPolicy.SOURCE)
public @interface MaritalStatus {
int SINGLE = 0;
int MARRIED = 1;
int DIVORCED = 2;
}

Now that’s seems better. Everything is organized. Is there any drawbacks though? I don’t know, that’s why I asked this question in StackOverFlow but haven’t get a satisfying answer.


ADTT (Android Development Tips and Tricks) is a 31 series of blog posts that I’m trying to finish in May. Click here for index.