Lavorare con Enums in Android


120

Ho quasi finito con un'attività di calcolo con cui sto lavorando in Android per la mia app. Provo a creare un Gender Enum, ma per qualche motivo ottengo un errore di sintassi, inserisco "EnumBody" per completare 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;
    }
}

L'ho provato anche senza la statica {} ma ottengo lo stesso errore di sintassi.


Le enumerazioni non sono consigliate per problemi di prestazioni, utilizzare invece costanti primitive. youtube.com/watch?v=Hzs6OBcvNQE
Myke Dev

UPDATE 2019: enumerazioni vanno bene per l'uso in Android dal ART sostituito Dalvik come ambiente runtime stackoverflow.com/a/56296746/4213436 . Pertanto penso che la maggior parte delle risposte su questo thread siano irrilevanti.
JDenais

@JDenais ovviamente intendi il thread "tu" appena citato
YoussefDir

Risposte:


343

Dove diavolo hai trovato questa sintassi? Java Enums sono molto semplici, devi solo specificare i valori.

public enum Gender {
   MALE,
   FEMALE
}

Se vuoi che siano più complessi, puoi aggiungere valori in questo modo.

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

Quindi per usare l'enumerazione, dovresti fare qualcosa del genere:

Gender me = Gender.MALE

12
Ci proverò, ho detto che ero un principiante assoluto
JMSDEV

87
Scusa, non intendevo negativamente. Solo la sintassi più strana che abbia mai visto per un Enum
Spidy

4
È anche utile menzionare che le enumerazioni sono sequenziali in modo da poter utilizzare .ordinal () sull'enumerazione per ottenere il valore int.
Kalel Wade

1
La sintassi nella domanda è del tipo che si potrebbe ottenere utilizzando un decompilatore.
Dan Getz

9
Ho riso così tanto su "Dove diavolo hai trovato questa sintassi". Dire proprio come un insegnante al suo studente
Zar E Ahmer

50

C'è stato un certo dibattito su questo punto di contesa, ma anche nei documenti più recenti Android suggerisce che non è una buona idea usare le enumerazioni in un'applicazione Android. Il motivo è perché utilizzano più memoria di una variabile con costanti statiche. Ecco un documento da una pagina del 2014 che sconsiglia l'uso di enumerazioni in un'applicazione Android.http://developer.android.com/training/articles/memory.html#Overhead

Quoto:

Sii consapevole del sovraccarico della memoria

Informati sui costi e sui costi generali della lingua e delle librerie che stai utilizzando e tieni a mente queste informazioni quando progetti la tua app, dall'inizio alla fine. Spesso, le cose in superficie che sembrano innocue possono in effetti avere una grande quantità di sovraccarico. Esempi inclusi:

  • Le enumerazioni spesso richiedono più del doppio della memoria rispetto alle costanti statiche. Dovresti assolutamente evitare di usare le enumerazioni su Android.

  • Ogni classe in Java (comprese le classi interne anonime) utilizza circa 500 byte di codice.

  • Ogni istanza di classe ha 12-16 byte di overhead di RAM.

  • Mettere una singola voce in una HashMap richiede l'allocazione di un oggetto di ingresso aggiuntivo che richiede 32 byte (vedere la sezione precedente sui contenitori di dati ottimizzati).

Alcuni byte qua e là si sommano rapidamente: i progetti di app che sono pesanti per classi o oggetti soffriranno di questo sovraccarico. Questo può lasciarti nella difficile posizione di guardare un'analisi dell'heap e rendersi conto che il tuo problema è che molti piccoli oggetti consumano la tua RAM.

Ci sono stati alcuni posti in cui si dice che questi suggerimenti sono obsoleti e non sono più preziosi, ma il motivo per cui continuano a ripeterlo, deve essere che c'è del vero. Scrivere un'applicazione Android è qualcosa che dovresti mantenere il più leggero possibile per un'esperienza utente fluida. E ogni piccolo centimetro di prestazioni conta!


Ci sono stati alcuni posti - potresti aggiungerne alcuni se li conosci? perché non riesco a trovarne nessuno
Krzysztof Skrzynecki

9
Qui qualcuno ha notato che le informazioni sull'utilizzo int al posto di enumerazioni è stato rimosso dal Trucchi per le prestazioni nella documentazione ufficiale. Inoltre, ho fatto ricerche e pubblicato un riepilogo su reddit
Krzysztof Skrzynecki


Ragazzi, la mia domanda è se Enum è una pratica "cattiva", perché Google supporta ancora questa funzione di Java con Android? :(
Jesús Castro

5
@ JesúsCastro Perché Google vuole garantire che le aziende con molta logica aziendale Java esistente (che potrebbero utilizzare enumerazioni) possano semplicemente inserire la loro libreria in un progetto Android e andare.
David Brown

22

Come commentato da Chris, le enumerazioni richiedono molta più memoria su Android che si aggiunge man mano che continuano ad essere utilizzate ovunque. Dovresti invece provare IntDef o StringDef , che usano annotazioni in modo che il compilatore convalidi i valori passati.

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

Può anche essere usato come flag, consentendo la composizione binaria (operazioni OR / AND).

EDIT : Sembra che trasformare le enumerazioni in int sia una delle ottimizzazioni predefinite in Proguard .


3
Mi piace inserire le costanti int direttamente nella classe di annotazione. Quindi sembra una enumerazione regolare. L'ho descritto qui: blog.shamanland.com/2016/02/int-string-enum.html
Oleksii K.


9

Secondo questo video se usi ProGuard non devi nemmeno pensare ai problemi di prestazioni di Enums !!

Proguard può in molte situazioni ottimizzare Enums su valori INT per tuo conto, quindi non c'è davvero bisogno di pensarci o fare alcun lavoro.


4

L'approccio preferito di Android sono le costanti int applicate con @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;
  }
}

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.