Working with Enums in android

AndroidEnums

Android Problem Overview


I am almost done with a calculation activity I am working with in android for my app. I try to create a Gender Enum, but for some reason getting Syntax error, insert "EnumBody" to complete EnumDeclaration.

public static enum Gender
{
    static
    {
        Female = new Gender("Female", 1);
        Gender[] arrayOfGender = new Gender[2];
        arrayOfGender[0] = Male;
        arrayOfGender[1] = Female;
        ENUM$VALUES = arrayOfGender;
    }
}

I have also tried it without the static {} but I get the same syntax error.

Android Solutions


Solution 1 - Android

Where on earth did you find this syntax? Java Enums are very simple, you just specify the values.

public enum Gender {
   MALE,
   FEMALE
}

If you want them to be more complex, you can add values to them like this.

public enum Gender {
	MALE("Male", 0),
	FEMALE("Female", 1);
	
	private String stringValue;
	private int intValue;
	private Gender(String toString, int value) {
		stringValue = toString;
		intValue = value;
	}
	
	@Override
	public String toString() {
		return stringValue;
	}
}

Then to use the enum, you would do something like this:

Gender me = Gender.MALE

Solution 2 - Android

There has been some debate around this point of contention, but even in the most recent documents android suggests that it's not such a good idea to use enums in an android application. The reason why is because they use up more memory than a static constants variable. Here is a document from a page of 2014 that advises against the use of enums in an android application. http://developer.android.com/training/articles/memory.html#Overhead

I quote:

> Be aware of memory overhead > > Be knowledgeable about the cost and overhead of the language and > libraries you are using, and keep this information in mind when you > design your app, from start to finish. Often, things on the surface > that look innocuous may in fact have a large amount of overhead. > Examples include: > >

> - Enums often require more than twice as much memory as static constants. You should strictly avoid using enums on Android.

>- Every class in Java (including anonymous inner classes) uses about 500 bytes of code.

>- Every class instance has 12-16 bytes of RAM overhead.

>

> - Putting a single entry into a HashMap requires the allocation of an additional entry object that takes 32 bytes (see the previous section about optimized data containers).

> A few bytes here and there quickly add > up—app designs that are class- or object-heavy will suffer from this > overhead. That can leave you in the difficult position of looking at a > heap analysis and realizing your problem is a lot of small objects > using up your RAM.

There has been some places where they say that these tips are outdated and no longer valuable, but the reason they keep repeating it, must be there is some truth to it. Writing an android application is something you should keep as lightweight as possible for a smooth user experience. And every little inch of performance counts!

Solution 3 - Android

As commented by Chris, enums require much more memory on Android that adds up as they keep being used everywhere. You should try IntDef or StringDef instead, which use annotations so that the compiler validates passed values.

public abstract class ActionBar {
...
@IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS})
@Retention(RetentionPolicy.SOURCE)
public @interface NavigationMode {}

public static final int NAVIGATION_MODE_STANDARD = 0;
public static final int NAVIGATION_MODE_LIST = 1;
public static final int NAVIGATION_MODE_TABS = 2;

@NavigationMode
public abstract int getNavigationMode();

public abstract void setNavigationMode(@NavigationMode int mode);

It can also be used as flags, allowing for binary composition (OR / AND operations).

EDIT: It seems that transforming enums into ints is one of the default optimizations in Proguard.

Solution 4 - Android

public enum Gender {
    MALE,
    FEMALE
}

Solution 5 - Android

According to this Video if you use the ProGuard you don't need even think about Enums performance issues!!

> Proguard can in many situations optimize Enums to INT values on your behalf so really don't need to think about it or do any work.

Solution 6 - Android

Android's preferred approach is int constants enforced with @IntDef:

public static final int GENDER_MALE = 1;
public static final int GENDER_FEMALE = 2;

@Retention(RetentionPolicy.SOURCE)
@IntDef ({GENDER_MALE, GENDER_FEMALE})
public @interface Gender{}

// Example usage...
void exampleFunc(@Gender int gender) {
  switch(gender) {
  case GENDER_MALE:

     break;
  case GENDER_FEMALE:
     // TODO
     break;
  }
}

Docs: https://developer.android.com/studio/write/annotations.html#enum-annotations

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJMSDEVView Question on Stackoverflow
Solution 1 - AndroidSpidyView Answer on Stackoverflow
Solution 2 - AndroidChrisView Answer on Stackoverflow
Solution 3 - AndroidNacho ColomaView Answer on Stackoverflow
Solution 4 - AndroidGabriel NegutView Answer on Stackoverflow
Solution 5 - AndroidHaniView Answer on Stackoverflow
Solution 6 - AndroidAnmView Answer on Stackoverflow