Bundle
다음과 같은 인터페이스에서 키와 같은 관련 상수 세트를 함께 정의했습니다 .
public interface From{
String LOGIN_SCREEN = "LoginSCreen";
String NOTIFICATION = "Notification";
String WIDGET = "widget";
}
이것은 관련 상수를 함께 그룹화하고 정적 가져 오기 (구현이 아님)를 만들어 사용하는 더 좋은 방법을 제공합니다. 내가 알고있는 Android
프레임 워크도 같은 동일한 방법으로 상수를 사용합니다 Toast.LENTH_LONG
, View.GONE
.
그러나 나는 종종 Java Enums
상수를 나타내는 훨씬 더 좋고 강력한 방법을 제공 한다고 느낍니다 .
그러나 사용의 성취도 문제가 enums
에가 Android
?
약간의 조사로 나는 혼란에 빠졌습니다. 이 질문에서
? 안드로이드의 성능 정보에서 제거 “당신 만의 int 필요 않도록 열거 형” 는 것이 분명 Google
제거했습니다 “피 열거 형을” 성능 팁에서, 그러나 그것의에서 공식 훈련 문서는 메모리 오버 헤드에주의 가 명확하게 말한다 절 : “열거 형을 종종 정적 상수보다 두 배 이상의 메모리가 필요합니다. Android에서 열거 형을 사용하는 것은 엄격히 피해야합니다. “ 여전히 유효합니까? (예 : Java
1.6 이후 버전)
내가 관찰 한 가지 더 문제가 전송하는 것입니다 enums
통해 intents
사용하여 Bundle
직렬화에 의해 내가 그들을 보내야합니다 (예 :putSerializable()
, 기본 putString()
메소드에 비해 비용이 많이 드는 작업이라고 생각하지만 enums
무료로 제공하지만).
누군가 같은 것을 표현하는 가장 좋은 방법이 무엇인지 명확히 해줄 수 있습니까 Android
? 에 사용 enums
을 엄격히 피해야 Android
합니까?
답변
enum
기능이 필요할 때 사용하십시오 . 엄격하게 피하지 마십시오 .
Java enum은 더 강력하지만 기능이 필요하지 않은 경우 상수를 사용하면 공간을 덜 차지하고 원시 자체가 될 수 있습니다.
열거 형을 사용하는 경우 :
- 당신이 받아 들일 수 – 유형 검사 만 (내가 부르는 아래 참조 목록에 값을, 그들은 연속없는 연속 여기)
-
메서드 오버로딩-모든 열거 형 상수에는 자체 메서드 구현이 있습니다.
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); }
-
더 많은 데이터-하나의 상수에 하나의 변수에 넣을 수없는 하나 이상의 정보가 포함되어 있습니다.
- 복잡한 데이터-데이터를 조작하는 데 필요한 방법
하면 되지 열거를 사용하는 방법 :
- 한 유형의 모든 값을 허용 할 수 있으며 상수에는 가장 많이 사용되는 값만 포함됩니다.
-
연속 데이터를받을 수 있습니다.
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); } ... } }
- 이름 (예를 들어)
- 실제로 열거 형이 필요하지 않은 다른 모든 것
열거 형은 더 많은 공간을 차지합니다.
- 열거 형 상수에 대한 단일 참조는 4 바이트를 차지 합니다.
- 모든 열거 형 상수는 8 바이트에 정렬 된 필드 크기 + 개체의 오버 헤드의 합계 인 공간을 차지 합니다.
- 열거 형 클래스 자체가 일부 공간을 차지합니다.
상수는 더 적은 공간을 차지합니다.
- 상수에는 참조가 없으므로 순수한 데이터입니다 (참조 인 경우에도 열거 형 인스턴스는 다른 참조에 대한 참조가 됨).
- 기존 클래스에 상수를 추가 할 수 있습니다. 다른 클래스를 추가 할 필요가 없습니다.
- 상수는 인라인 될 수 있습니다. 확장 된 컴파일 타임 기능을 제공합니다 (예 : null 검사, 데드 코드 찾기 등).
답변
열거 형에 단순히 값이있는 경우 다음과 같이 IntDef / StringDef를 사용해야합니다.
https://developer.android.com/studio/write/annotations.html#enum-annotations
예 : 대신 :
enum NavigationMode {NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS}
너는 사용한다:
@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);
열거 형이 복잡한 경우 열거 형을 사용하십시오. 그렇게 나쁘진 않아.
열거 형과 상수 값을 비교하려면 여기를 읽어야합니다.
http://hsc.com/Blog/Best-Practices-For-Memory-Optimization-on-Android-1
그들의 예는 2 개의 값이있는 열거 형입니다. 상수 정수를 사용할 때 128 바이트에 비해 dex 파일에서 1112 바이트를 사용합니다. 열거 형이 실제 클래스이므로 C / C ++에서 작동하는 방식과는 대조적으로 의미가 있습니다.
답변
이전 답변 외에도 Proguard를 사용하는 경우 (확실히 크기를 줄이고 코드를 난독 화하기 위해 수행해야 함) 가능한 모든 곳 Enums
으로 자동 변환됩니다 @IntDef
.
https://www.guardsquare.com/en/proguard/manual/optimizations
클래스 / 언 박싱 / 열거 형
가능한 경우 열거 형 유형을 정수 상수로 단순화합니다.
따라서 일부 불연속 값이 있고 일부 메서드가 동일한 유형의 다른 값이 아닌이 값만 사용할 수 있도록 허용해야하는 경우 Enum
Proguard가이 수동 코드 최적화 작업을 수행 할 것이기 때문에를 사용 합니다.
그리고 여기에 Jake Wharton의 열거 형 사용에 대한 좋은 게시물이 있습니다.
라이브러리 개발자로서 저는 소비하는 앱의 크기, 메모리 및 성능에 가능한 한 영향을 미치지 않기 위해 수행해야하는 이러한 작은 최적화를 인식합니다. 그러나 […] 공용 API에 열거 형 대 정수 값을 적절한 곳에 두는 것이 완벽하다는 사실을 인식하는 것이 중요합니다. 정보에 입각 한 결정을 내리는 차이를 아는 것이 중요합니다.
답변
Android에서 열거 형 사용을 엄격히 피해야합니까?
아니요. ” 엄격하게 “는 너무 나빠서 전혀 사용해서는 안된다는 의미입니다. 열거 형 (ui 스레드에서 연속)을 사용하는 많은 (수천 또는 수백만) 작업과 같은 극단적 인 상황에서 성능 문제가 발생할 수 있습니다 . 훨씬 더 일반적인 것은 백그라운드 스레드에서 엄격하게 발생 해야하는 네트워크 I / O 작업입니다 . 열거의 가장 일반적인 사용은 아마 유형 검사의 일종입니다 – 객체인지 확인 이 또는 그것을 너무 빨리 당신이 열거 형의 단일 비교 및 정수의 비교 사이의 차이를 발견 할 수 없습니다이다.
누군가가 Android에서 동일한 것을 나타내는 가장 좋은 방법을 명확히 할 수 있습니까?
이것에 대한 일반적인 경험 법칙은 없습니다. 자신에게 맞는 것을 사용하고 앱을 준비하는 데 도움이됩니다. 나중에 최적화-앱의 일부 측면을 느리게하는 병목 현상이 있음을 확인한 후.
답변
Android P에서 Google은 열거 형 사용에 제한 / 이의가 없습니다.
문서는 이전에주의하도록 권장되었던 곳에서 변경되었지만 지금은 언급하지 않습니다.
https://developer.android.com/reference/java/lang/Enum
답변
두 가지 사실.
1, Enum은 JAVA에서 가장 강력한 기능 중 하나입니다.
2, Android 휴대 전화에는 일반적으로 많은 메모리가 있습니다.
그래서 제 대답은 아니오입니다. Android에서 Enum을 사용하겠습니다.
답변
추가하고 싶습니다. 키 또는 값이 주석 인터페이스 중 하나 인 List <> 또는 Map <>을 선언 할 때 @Annotations를 사용할 수 없습니다. “여기에는 주석을 사용할 수 없습니다.”라는 오류가 표시됩니다.
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 ***
따라서 목록 / 맵으로 압축해야 할 때 enum을 사용하십시오. 추가 할 수 있지만 @annotated int / string 그룹은 할 수 없습니다.