以下のようなインターフェースで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が必要なEnumを避ける」はAndroidのパフォーマンスのヒントから削除されましたか?Google
が削除されたことは明らかです「Avoid enums」パフォーマンスのヒントからですが、公式のトレーニングドキュメントから メモリオーバーヘッドに注意してください セクションには次のように明記されています:静的定数として。 Androidでは列挙型の使用を厳密に避ける必要があります。 "これは引き続き有効ですか?(たとえば、Java
バージョン1.6以降)
私が観察したもう1つの問題は、enums
を使用してintents
を介してBundle
を送信することです。それらをシリアル化して送信する必要があります(つまり、putSerializable()
、enums
は無料で提供していますが、プリミティブなputString()
メソッドと比較して高価な操作だと思います)。
誰かがAndroid
で同じものを表すための最良の方法であるものを明確にしていただけますか? enums
でAndroid
を使用することを厳密に避けるべきですか?
機能が必要な場合は、enum
を使用します。 回避しないでくださいstrictly.
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);
}
より多くのデータ-1つの定数には、1つの変数に入れることができない複数の情報が含まれています
連続データを受け入れることができます
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);
}
...
}
}
列挙型に値がある場合は、次に示すようにIntDef/StringDefを使用する必要があります。
http://tools.Android.com/tech-docs/support-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
class/unboxing/enum
可能な場合は常に、列挙型を整数定数に単純化します。
したがって、いくつかの離散値があり、一部の方法でこの値のみを使用し、同じタイプの他の値は使用できない場合は、Enum
を使用します。Proguardがこの手動のコード最適化作業を行うためです。
そして こちら Jake Whartonの列挙型の使用に関する良い投稿です。
ライブラリ開発者として、消費するアプリのサイズ、メモリ、パフォーマンスにできるだけ影響を与えたくないため、これらの小さな最適化を行う必要があることを認識しています。しかし、[...]パブリックAPIに列挙型を配置することと、適切な場合には整数値を配置することは完全に適切であることを認識することが重要です。情報に基づいた意思決定を行うための違いを知ることが重要です
Androidで列挙型の使用を厳密に避けるべきですか?
いいえ。 "Strictly"は、それらが非常に悪いことを意味し、まったく使用すべきではありません。 多くの多く(数千または数百万)の列挙(UIスレッドで連続)のような極端な状況では、パフォーマンスの問題が発生する可能性があります。より一般的なのは、バックグラウンドスレッドでstrictlyが発生するネットワークI/O操作です。列挙型の最も一般的な使用法は、おそらく何らかの種類のチェックです-オブジェクトがthisかthatであるかどうかは非常に高速であるため、列挙の単一の比較と整数の比較。
誰かがAndroidで同じものを表現するための最良の方法であるものを明確にしていただけますか?
これに関する一般的な経験則はありません。自分に合ったものをすべて使用し、アプリの準備を支援します。後で最適化-気づいた後、アプリのいくつかの側面を遅くするボトルネックがあります。
Android Pを使用すると、enumを使用する際にgoogleに制限/異議はありません
ドキュメントは、以前は注意を払うことが推奨されていた場所を変更しましたが、現在は言及していません。 https://developer.Android.com/reference/Java/lang/Enum
2つの事実。
1、EnumはJavaの最も強力な機能の1つです。
2、Android電話には通常、大量のメモリがあります。
だから私の答えはNOです。 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グループは追加できません。