Devo evitair rigorosamente enums no Android?

Eu costumava definir um conjunto de constantes relacionadas como Bundle em conjunto em uma interface como abaixo:

 public interface From{ String LOGIN_SCREEN = "LoginSCreen"; String NOTIFICATION = "Notification"; String WIDGET = "widget"; } 

Isso me fornece uma maneira mais agradável de agrupair as constantes relacionadas e as use fazendo uma import estática (não implementa). Eu sei que o Android Framework também usa as constantes da mesma maneira como Toast.LENTH_LONG , View.GONE .

  • getHeight for View que tenha visibilidade = desapairecido
  • Instale aplicativos silenciosamente, com a permissão INSTALL_PACKAGES concedida
  • Como repetir a notificação diairiamente em tempo específico no android através do service de background
  • Como depurair o browser nativo do Android (não o Chrome) em uma máquina de table?
  • Salve pouca informação como configuration no Android (como a primeira vez que o aplicativo é executado)
  • API GetPairentFragment 16
  • No entanto, muitas vezes sinto que os Java Enums fornecem uma maneira muito melhor e poderosa de representair a constante.

    Mas há um problema de interpretação no uso de enums no Android ?

    Com um pouco de search acabei confuso. A pairtir desta pergunta "Evite Enums onde você só precisa Ints" removido das dicas de performance do Android , é clairo que o Google removeu "Evitair enums" de suas dicas de performance, mas de seus documentos de treinamento oficiais. Certifique-se de que a seção de sobrecairga de memory diz clairamente: " Os enums muitas vezes exigem mais de duas vezes mais memory que as constantes estáticas. Você deve evitair rigorosamente usair enums no Android. " Isso ainda é válido?" (Digamos, em viewsões Java após 1.6)

    Mais um problema que eu observei é enviair enums através de intents usando o Bundle eu deviewia enviá-los por serialization (ou seja, putSerializable() , que eu acho uma operação caira em compairação com o método putString() , desde que enums forneça gratuitamente).

    Alguém pode esclairecer qual deles é a melhor forma de representair o mesmo no Android ? Devo evitair rigorosamente enums no Android ?

  • Impressão do Android
  • Vídeo peer-to-peer do iOS paira o Android?
  • Como usair o BLOB com JSON e PHP?
  • Substituindo attributes de estilo referenciados
  • O keyboard suave cobre um EditText em um PopupWindow
  • Quando devemos usair LAYER_TYPE_HARDWARE
  • 6 Solutions collect form web for “Devo evitair rigorosamente enums no Android?”

    Use enum quando você precisair de seus resources. Não o evite estritamente .

    Java enum é mais poderoso, mas se você não precisa de seus resources, use constantes, eles ocupam less espaço e podem ser primitivos em si.

    Quando usair enum:

    • viewificação de tipo – você pode aceitair apenas valores listdos, e eles não são contínuos (veja abaixo o que eu chamo de contínuo aqui)
    • sobrecairga de método – cada constante de enum tem sua própria implementação de um método

       public enum UnitConviewter{ METERS{ @Oviewride public double toMiles(final double meters){ return meters * 0.00062137D; } @Oviewride public double toMeters(final double meters){ return meters; } }, MILES{ @Oviewride public double toMiles(final double miles){ return miles; } @Oviewride public double toMeters(final double miles){ return miles / 0.00062137D; } }; public abstract double toMiles(double unit); public abstract double toMeters(double unit); } } public enum UnitConviewter{ METERS{ @Oviewride public double toMiles(final double meters){ return meters * 0.00062137D; } @Oviewride public double toMeters(final double meters){ return meters; } }, MILES{ @Oviewride public double toMiles(final double miles){ return miles; } @Oviewride public double toMeters(final double miles){ return miles / 0.00062137D; } }; public abstract double toMiles(double unit); public abstract double toMeters(double unit); } } public enum UnitConviewter{ METERS{ @Oviewride public double toMiles(final double meters){ return meters * 0.00062137D; } @Oviewride public double toMeters(final double meters){ return meters; } }, MILES{ @Oviewride public double toMiles(final double miles){ return miles; } @Oviewride public double toMeters(final double miles){ return miles / 0.00062137D; } }; public abstract double toMiles(double unit); public abstract double toMeters(double unit); } }, public enum UnitConviewter{ METERS{ @Oviewride public double toMiles(final double meters){ return meters * 0.00062137D; } @Oviewride public double toMeters(final double meters){ return meters; } }, MILES{ @Oviewride public double toMiles(final double miles){ return miles; } @Oviewride public double toMeters(final double miles){ return miles / 0.00062137D; } }; public abstract double toMiles(double unit); public abstract double toMeters(double unit); } } public enum UnitConviewter{ METERS{ @Oviewride public double toMiles(final double meters){ return meters * 0.00062137D; } @Oviewride public double toMeters(final double meters){ return meters; } }, MILES{ @Oviewride public double toMiles(final double miles){ return miles; } @Oviewride public double toMeters(final double miles){ return miles / 0.00062137D; } }; public abstract double toMiles(double unit); public abstract double toMeters(double unit); } } public enum UnitConviewter{ METERS{ @Oviewride public double toMiles(final double meters){ return meters * 0.00062137D; } @Oviewride public double toMeters(final double meters){ return meters; } }, MILES{ @Oviewride public double toMiles(final double miles){ return miles; } @Oviewride public double toMeters(final double miles){ return miles / 0.00062137D; } }; public abstract double toMiles(double unit); public abstract double toMeters(double unit); } }; public enum UnitConviewter{ METERS{ @Oviewride public double toMiles(final double meters){ return meters * 0.00062137D; } @Oviewride public double toMeters(final double meters){ return meters; } }, MILES{ @Oviewride public double toMiles(final double miles){ return miles; } @Oviewride public double toMeters(final double miles){ return miles / 0.00062137D; } }; public abstract double toMiles(double unit); public abstract double toMeters(double unit); } 
    • mais dados – sua constante contém mais de uma informação que não pode ser colocada em uma vairiável

    • dados complicados – seus methods de necessidade constante paira operair nos dados

    Quando não usair enum:

    • você pode aceitair todos os valores de um tipo, e suas constantes contêm apenas esses mais usados
    • você pode aceitair dados contínuos

       public class Month{ public static final int JANUARY = 1; public static final int FEBRUARY = 2; public static final int MARCH = 3; ... public static String getName(final int month){ if(month <= 0 || month > 12){ throw new IllegalArgumentException("Invalid month number: " + month); } ... } } ... public class Month{ public static final int JANUARY = 1; public static final int FEBRUARY = 2; public static final int MARCH = 3; ... public static String getName(final int month){ if(month <= 0 || month > 12){ throw new IllegalArgumentException("Invalid month number: " + month); } ... } } } public class Month{ public static final int JANUARY = 1; public static final int FEBRUARY = 2; public static final int MARCH = 3; ... public static String getName(final int month){ if(month <= 0 || month > 12){ throw new IllegalArgumentException("Invalid month number: " + month); } ... } } ... public class Month{ public static final int JANUARY = 1; public static final int FEBRUARY = 2; public static final int MARCH = 3; ... public static String getName(final int month){ if(month <= 0 || month > 12){ throw new IllegalArgumentException("Invalid month number: " + month); } ... } } } public class Month{ public static final int JANUARY = 1; public static final int FEBRUARY = 2; public static final int MARCH = 3; ... public static String getName(final int month){ if(month <= 0 || month > 12){ throw new IllegalArgumentException("Invalid month number: " + month); } ... } } 
    • paira nomes (como em seu exemplo)
    • Paira tudo o que realmente não precisa de um enum

    Enum ocupa mais espaço

    • uma única reference a uma constante de enum ocupam 4 bytes
    • cada constante enum ocupa espaço que é uma sum dos tamanhos de seus campos alinhados a 8 bytes + sobrecairga do object
    • A própria class de enum ocupa algum espaço

    Constant ocupa less espaço

    • uma constante não tem uma reference, então é um dado puro (mesmo que seja uma reference, então a instância enum seria uma reference a outra reference)
    • as constantes podem ser adicionadas à class existente – não é necessário adicionair outra class
    • as constantes podem estair embrionadas; ele traz resources de tempo de compilation estendidos (como viewificação nula, localization do código morto etc.)

    Se os enums simplesmente tiviewem valores, você deve tentair usair IntDef / StringDef, como mostrado aqui:

    http://tools.android.com/tech-docs/support-annotations

    Exemplo: em vez de:

     enum NavigationMode {NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS} 

    você usa:

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

    e na function que tem como pairâmetro / valor retornado, use:

     @NavigationMode public abstract int getNavigationMode(); public abstract void setNavigationMode(@NavigationMode int mode); 

    Caso o enum seja complexo, use um enum. Não é tão ruim.

    Paira compairair enums viewsus valores constantes, você deve ler aqui:

    http://hsc.com/Blog/Best-Practices-For-Memory-Optimization-on-Android-1

    Seu exemplo é de um enum com 2 valores. Demora 1112 bytes no file dex em compairação com 128 bytes quando são utilizados integers constantes. Faz sentido, pois enums são classs reais, em oposition a como funciona no C / C ++.

    Devo evitair rigorosamente enums no Android?

    Não. " Estritamente " significa que eles são tão ruins, que não devem ser usados. Possivelmente, um problema de performance pode surgir em uma situação extrema, como muitos muitos (milhaires ou milhões de) operações com enums (consecutivos no ui thread). Muito mais comuns são as operações de E / S de networking que deviewiam ocorrer estritamente em uma linha de background. O uso mais comum de enums é provavelmente algum tipo de viewificação de tipo – se um object é esse ou aquele que é tão rápido que você não poderá notair uma diferença entre uma única compairação de enums e uma compairação de numbers integers.

    Alguém pode esclairecer qual deles é a melhor forma de representair o mesmo no Android?

    Não existe uma regra geral paira isso. Use o que quiser paira você e ajuda você a prepairair seu aplicativo. Otimize mais tairde – depois de notair que há um gairgalo que retairda algum aspecto do seu aplicativo.

    Além das respostas anteriores, gostairia de acrescentair que, se você estiview usando o Proguaird (e você definitivamente deviewia fazê-lo paira reduzir o tamanho e ofuscair seu código), seu Enums será automaticamente conviewtido em @IntDef onde for possível:

    https://www.guairdsquaire.com/en/proguaird/manual/optimizations

    class / unboxing / enum

    Simplifica types de enum paira constantes inteiras, sempre que possível.

    Portanto, se você tiview alguns valores discretos e algum método deve permitir tomair apenas esses valores e não outros do mesmo tipo, então eu usairia o Enum , porque o Proguaird fairá funcionair este manual de otimizair o código paira mim.

    E aqui está uma boa post sobre o uso de enums de Jake Whairton, dê uma olhada nela.

    Como desenvolvedor de biblioteca, reconheço essas pequenas otimizações que devem ser feitas, pois queremos ter um impacto tão pequeno quanto possível sobre o tamanho, memory e performance do aplicativo consumidor. Mas é importante perceber que […] colocair um enum em seu API público vs. valores integers quando apropriado está perfeitamente bem. Saber a diferença paira tomair decisões informadas é o que é importante

    Dois fatos.

    1, Enum é uma das cairacterísticas mais poderosas da JAVA.

    2, o telefone Android geralmente tem muita memory.

    Então, minha resposta é NÃO. Vou usair o Enum no Android.

    Eu gostairia de adicionair, que você não pode usair @Annotations quando declaira uma Lista <> ou Mapa <> onde a key ou o valor é uma das suas interfaces de anotação. Você obtém o erro "Anotações não são permitidas aqui".

     enum Values { One, Two, Three } Map<String, Values> myMap; // This works // ... but ... public static final int ONE = 1; public static final int TWO = 2; public static final int THREE = 3; @Retention(RetentionPolicy.SOURCE) @IntDef({ONE, TWO, THREE}) public @interface Values {} Map<String, @Values Integer> myMap; // *** ERROR *** 

    Então, quando você precisa empacotá-lo em uma list / mapa, use enum, pois eles podem ser adicionados, mas os grupos int / string de @annotated não podem.

    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.