nvi*_*tty 90 java enums android
我过去常常Bundle在如下界面中定义一组相关常量(如键):
public interface From{
String LOGIN_SCREEN = "LoginSCreen";
String NOTIFICATION = "Notification";
String WIDGET = "widget";
}
Run Code Online (Sandbox Code Playgroud)
这为我提供了一种更好的方法来将相关常量组合在一起并通过静态导入(而不是实现)来使用它们.我知道Android框架也使用常数在同样的方式一样Toast.LENTH_LONG,View.GONE.
但是,我经常觉得Java Enums提供更好,更强大的方式来表示常数.
但是,有没有在使用性能自动问题enums上Android?
通过一些研究,我最终陷入困惑.从Android的性能提示Google中删除了"避免使用只需要Ints的枚举"的问题
吗?显然已经从其性能提示中删除了"避免枚举",但是从它的官方培训文档中了解内存开销部分它清楚地说:"枚举通常需要的内存是静态常量的两倍多.你应该严格避免在Android上使用枚举."这仍然很好吗?(Java在1.6之后的版本中说)
我观察到的一个问题,更是发送enums跨intents使用Bundle我应该序列化给他们(即putSerializable(),我认为一个昂贵的操作比较原始的putString()方法沉绵enums提供它是免费的).
有人可以澄清哪一个是代表相同的最佳方式Android?我应该严格避免使用enums的Android?
Kam*_*osz 107
enum在需要其功能时使用.不要严格避免它.
Java枚举更强大,但如果你不需要它的特性,使用常量,它们占用的空间更少,它们本身也可以是原始的.
方法重载 - 每个枚举常量都有自己的方法实现
public enum UnitConverter{
METERS{
@Override
public double toMiles(final double meters){
return meters * 0.00062137D;
}
@Override
public double toMeters(final double meters){
return meters;
}
},
MILES{
@Override
public double toMiles(final double miles){
return miles;
}
@Override
public double toMeters(final double miles){
return miles / 0.00062137D;
}
};
public abstract double toMiles(double unit);
public abstract double toMeters(double unit);
}
Run Code Online (Sandbox Code Playgroud)更多数据 - 您的一个常量包含多个不能放在一个变量中的信息
你可以接受连续的数据
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);
}
...
}
}
Run Code Online (Sandbox Code Playgroud)and*_*per 57
如果枚举只有值,你应该尝试使用IntDef/StringDef,如下所示:
http://tools.android.com/tech-docs/support-annotations
示例:代替:
enum NavigationMode {NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS}
Run Code Online (Sandbox Code Playgroud)
你用:
@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;
Run Code Online (Sandbox Code Playgroud)
并在将其作为参数/返回值的函数中,使用:
@NavigationMode
public abstract int getNavigationMode();
public abstract void setNavigationMode(@NavigationMode int mode);
Run Code Online (Sandbox Code Playgroud)
如果枚举很复杂,请使用枚举.没那么糟糕.
要比较枚举与常量值,您应该在此处阅读:
http://hsc.com/Blog/Best-Practices-For-Memory-Optimization-on-Android-1
他们的例子是一个包含2个值的枚举.在dex文件中需要1112个字节,而使用常量整数时需要128个字节.有道理,因为枚举是真正的类,而不是它在C/C++上的工作方式.
sta*_*an0 11
我应该严格避免在Android上使用枚举吗?
不," 严格 "意味着它们非常糟糕,根本不应该使用它们.可能在极端情况下会出现性能问题,例如许多(数千或数百万)带枚举的操作(在ui线程上连续).更常见的是应该在后台线程中严格发生的网络I/O操作.枚举的最常见的用法可能是某种类型的检查-一个对象是否是这个或那个它是如此之快,你将无法注意到枚举的比较单一和整数的比较之间的差异.
有人可以澄清哪一个是在Android中表示相同的最佳方式?
对此没有一般的经验法则.使用适用于您的任何内容并帮助您准备好应用程序.稍后进行优化 - 在您发现有一个瓶颈会减慢应用程序的某些方面.
Gak*_*ket 11
除了之前的答案,我想补充一点,如果你使用的是Proguard(你绝对应该这样做以减小尺寸并混淆你的代码),那么你Enums将自动转换到@IntDef任何可能的地方:
https://www.guardsquare.com/en/proguard/manual/optimizations
类/拆箱/枚举
尽可能将枚举类型简化为整数常量.
因此,如果你有一些离散值,某些方法应该只允许这个值而不是同一类型的其他值,那么我会使用Enum,因为Proguard会让这个手册为我优化代码.
而这里是 如何使用枚举从杰克沃顿好的帖子,看看它.
作为一名库开发人员,我认识到应该完成的这些小优化,因为我们希望尽可能减少对消费应用程序的大小,内存和性能的影响.但重要的是要认识到在适当的情况下将公共API与整数值放在一起是完全正确的.了解差异以做出明智的决定是重要的
Ali*_*Ali 10
使用Android P,谷歌在使用枚举时没有任何限制/异议
在建议谨慎之前,文档已经发生了变化,但现在却没有提及. https://developer.android.com/reference/java/lang/Enum