【问题标题】:Working with Enums in android在 android 中使用枚举
【发布时间】:2012-03-04 01:16:11
【问题描述】:

我几乎完成了我在 android 中为我的应用程序使用的计算活动。我尝试创建一个性别枚举,但由于某种原因得到语法错误,插入“EnumBody”以完成 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;
    }
}

我也尝试过不使用静态 {},但我得到了相同的语法错误。

【问题讨论】:

  • 不推荐使用枚举来解决性能问题,而是使用原始常量。 youtube.com/watch?v=Hzs6OBcvNQE
  • 2019 年更新:枚举可以在 Android 中使用,因为 ART 取代了 DALVK 作为运行时环境stackoverflow.com/a/56296746/4213436。因此,我认为该线程上的大多数答案都是无关紧要的。
  • @JDenais 当然你的意思是“你”刚刚引用的线程

标签: android enums


【解决方案1】:

你到底是在哪里找到这种语法的? Java 枚举非常简单,您只需指定值即可。

public enum Gender {
   MALE,
   FEMALE
}

如果您希望它们更复杂,可以像这样为它们添加值。

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

然后要使用枚举,你可以这样做:

Gender me = Gender.MALE

【讨论】:

  • 我会试一试,我确实说过我是一个绝对的初学者
  • 对不起,我不是这个意思。这是我见过的最奇怪的枚举语法
  • 提及枚举是连续的也很有帮助,因此您可以在枚举上使用 .ordinal() 来获取 int 值。
  • 问题中的语法是使用反编译器可能得出的那种语法。
  • 我对“你到底从哪里找到这种语法”笑得这么厉害。像老师一样对学生说
【解决方案2】:

围绕这一争论点存在一些争论,但即使在最近的文档中,android 也表明在 android 应用程序中使用枚举并不是一个好主意。原因是因为它们比静态常量变量占用更多的内存。这是 2014 年页面中的一个文档,该文档建议不要在 android 应用程序中使用枚举。 http://developer.android.com/training/articles/memory.html#Overhead

我引用:

注意内存开销

了解语言的成本和开销,以及 您正在使用的库,并在使用时牢记这些信息 从头到尾设计您的应用程序。很多时候,表面上的东西 看起来无害的实际上可能有大量开销。 示例包括:

  • 枚举通常需要两倍于静态的内存 常数。您应该严格避免在 Android 上使用枚举。

  • Java 中的每个类(包括匿名内部类)使用大约 500 字节的代码。

  • 每个类实例都有 12-16 字节的 RAM 开销。

  • 将单个条目放入 HashMap 需要分配一个 额外的 占用 32 个字节的入口对象(参见上一节关于 优化的数据容器)。

这里那里几个字节快速添加 up — 类或对象重的应用程序设计将受此影响 高架。这会让你处于一个困难的境地 堆分析并意识到你的问题是很多小对象 用完你的内存。

有些地方他们说这些技巧已经过时并且不再有价值,但是他们不断重复的原因一定是有一些道理。编写一个 android 应用程序是你应该尽可能保持轻量级的东西,以获得流畅的用户体验。每一寸表现都很重要!

【讨论】:

  • 有一些地方 - 如果你知道的话,你能补充一些吗?因为我找不到任何
  • Here 有人注意到官方文档中的Performance Tips 删除了有关使用整数而不是枚举的信息。此外,我进行了研究并发布了summary on reddit
  • 伙计们,我的问题是,如果 Enum 是“不好”的做法,为什么 Google 仍然支持 Java 与 Android 的这一功能? :(
  • @JesúsCastro 因为 Google 希望确保拥有大量现有 Java 业务逻辑(可能正在使用枚举)的公司可以将他们的库放入 Android 项目中然后继续。
【解决方案3】:

正如 Chris 所评论的,枚举在 Android 上需要更多的内存,因为它们在任何地方都被使用,所以这些内存加起来。您应该尝试使用 IntDefStringDef 代替,它们使用注释以便编译器验证传递的值。

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

它也可以用作标志,允许二进制组合(OR / AND 操作)。

编辑:似乎将枚举转换为整数是one of the default optimizations in Proguard

【讨论】:

【解决方案4】:
public enum Gender {
    MALE,
    FEMALE
}

【讨论】:

    【解决方案5】:

    根据Video,如果您使用 ProGuard,您甚至不需要考虑 Enums 性能问题!

    Proguard 在许多情况下可以代表您将 Enums 优化为 INT 值,因此真的不需要考虑或做任何工作。

    【讨论】:

      【解决方案6】:

      Android 的首选方法是使用 @IntDef 强制执行 int 常量:

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

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

      【讨论】:

        猜你喜欢
        • 2012-09-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-29
        • 2023-04-04
        • 2012-03-20
        相关资源
        最近更新 更多