web-dev-qa-db-fra.com

Travailler avec Enums dans android

J'ai presque terminé une activité de calcul avec laquelle je travaille dans Android pour mon application. J'essaie de créer un genre Enum, mais pour une raison quelconque, obtenir erreur de syntaxe, insérez "EnumBody" pour compléter 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;
    }
}

Je l'ai également essayé sans le static {} mais j'obtiens la même erreur de syntaxe.

114
JMSDEV

Où avez-vous trouvé cette syntaxe? Java Les énumérations sont très simples, il vous suffit de spécifier les valeurs.

public enum Gender {
   MALE,
   FEMALE
}

Si vous souhaitez qu’ils soient plus complexes, vous pouvez leur ajouter des valeurs comme ceci.

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;
    }
}

Ensuite, pour utiliser l'énumération, vous feriez quelque chose comme ceci:

Gender me = Gender.MALE
328
Spidy

Il y a eu un débat autour de ce point de discorde, mais même dans les documents les plus récents, Android suggère que ce n'est pas une si bonne idée d'utiliser des énumérations dans une application Android. La raison en est qu’ils utilisent plus de mémoire qu’une variable de constantes statiques. Voici un document d'une page de 2014 qui déconseille l'utilisation d'énums dans une application Android. http://developer.Android.com/training/articles/memory.html#Overhead

Je cite:

Soyez conscient de la surcharge de mémoire

Familiarisez-vous avec les coûts et les frais généraux du langage et des bibliothèques que vous utilisez, et gardez cette information à l'esprit lorsque vous concevez votre application, du début à la fin. Souvent, les éléments à la surface qui semblent inoffensifs peuvent en réalité avoir une grande quantité de frais généraux. Les exemples comprennent:

  • Les énumérations nécessitent souvent plus de deux fois plus de mémoire que les constantes statiques. Vous devriez strictement éviter d'utiliser des enums sur Android.

  • Chaque classe de Java (y compris les classes internes anonymes) utilise environ 500 octets de code.

  • Chaque instance de classe a 12-16 octets de RAM overhead.

  • L'insertion d'une seule entrée dans un tableau de hachage nécessite l'allocation d'un objet d'entrée supplémentaire prenant 32 octets (voir la section précédente sur les conteneurs de données optimisés).

Quelques octets s'additionnent rapidement ici: les conceptions d'application lourdes en classes ou en objets pâtiront de cette surcharge. Cela peut vous laisser dans la position difficile de regarder une analyse de tas et de comprendre que votre problème est constitué de beaucoup de petits objets qui utilisent votre RAM.

Il y a eu des endroits où ils disent que ces astuces sont obsolètes et n'ont plus de valeur, mais la raison pour laquelle elles ne cessent de le répéter, c'est qu'il y a une part de vérité. L'écriture d'une application Android est une chose à garder aussi légère que possible pour une expérience utilisateur fluide. Et chaque petit pouce de performance compte!

49
Chris

Comme le commente Chris, les enums nécessitent beaucoup plus de mémoire sur Android, ce qui s’ajoute au fur et à mesure de leur utilisation continue. Vous devriez plutôt essayer IntDef ou StringDef , qui utilisent des annotations pour que le compilateur valide les valeurs transmises.

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);

Il peut également être utilisé comme indicateur, permettant une composition binaire (opérations OR/AND).

EDIT: Il semble que transformer des enums en ints soit ne des optimisations par défaut de Proguard .

22
Nacho Coloma
public enum Gender {
    MALE,
    FEMALE
}
17
Gabriel Negut

Selon cette Vidéo si vous utilisez le ProGuard, vous n'avez même pas besoin de penser aux problèmes de performances d'Enums !!

Proguard peut dans de nombreuses situations optimiser les valeurs Enums to INT en votre nom, vous n'avez donc pas besoin de réfléchir ni de travailler.

9
Hani

L'approche préférée d'Android est les constantes internationales appliquées avec @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

3
Anm