February 06, 2016

Android Dev Tips: How to replace Enum by int or String efficiently?

There's a good topic on developer.android.com about how to manage app's memory. I want to touch specific paragraph about enums:
Enums often require more than twice as much memory as static constants. You should strictly avoid using enums on Android.
Lot of developers don't want to follow this rule, saying this is inconvenient, hard to navigate through code, hard to debug, blah-blah-blah... 

Android guys want to help developers with this. They provided android.support.annotation package with lot of powerful annotations for Android Studio and Lint. I want to explain more about IntDef and StringDef. There two classes may help to replace enums efficiently for both: performance and convenience.

Let's look at two typical enum classes:

two enum declarations

Nothing special, short set of logically named constants. If we replace them by static final variables, then we'll automatically loose completeness of these declarations. It will be set of unlinked constants. Here is good tutorial how to use android annotations. It says:

The @IntDef annotation lets you basically create a "typedef", where you create another annotation which represents the valid integer constants that you expect, and then you decorate your API with this typedef annotation.

It's okay, good idea. But what if we'll go even further? We will place our constants directly in the annotation class, like this:

two annotations with constants inside

It looks a bit more complicated then enum declaration, but let's check how it works in code. Here is the simplest class declaration with two fields representing our enums. All we need to do is just mark both: fields and accessors with the annotations.

simple class with two fields of types int and String marked with annotations declared above

And now let's try to assign some values out of declared constants set. You can see error messages directly in editor.

example of error messages

It also works for switch-statement.

example of using switch-statement

Thus we can replace enum classes by simple constants without losing comfort of using strictly declared types. Beside that we improve performance of our apps.

Source code of this example is here.