これは古い質問ですが、列挙型は実際にSerializableあり、したがって、エクステントとしてインテントに完全に追加できることは誰もが言及していません。このような:
public enum AwesomeEnum {
SOMETHING, OTHER;
}
intent.putExtra("AwesomeEnum", AwesomeEnum.SOMETHING);
AwesomeEnum result = (AwesomeEnum) intent.getSerializableExtra("AwesomeEnum");
静的変数またはアプリケーション全体の変数を使用するという提案は、非常に悪い考えです。これは実際にあなたの活動を状態管理システムに結びつけます、そして維持し、デバッグし、問題を束縛することは困難です。
代替案:
Oderikによって提供されたソリューションがエラーを与えるという事実についてtedzycは良い点を指摘しました。ただし、提供される代替案は、使用するのが少し面倒です(ジェネリックを使用する場合でも)。
インテントに列挙型を追加することのパフォーマンスが本当に心配な場合は、代わりに次の代替案を提案します。
オプション1:
public enum AwesomeEnum {
SOMETHING, OTHER;
private static final String name = AwesomeEnum.class.getName();
public void attachTo(Intent intent) {
intent.putExtra(name, ordinal());
}
public static AwesomeEnum detachFrom(Intent intent) {
if(!intent.hasExtra(name)) throw new IllegalStateException();
return values()[intent.getIntExtra(name, -1)];
}
}
使用法:
// Sender usage
AwesomeEnum.SOMETHING.attachTo(intent);
// Receiver usage
AwesomeEnum result = AwesomeEnum.detachFrom(intent);
オプション2:(
一般的、再利用可能、列挙型から分離)
public final class EnumUtil {
public static class Serializer<T extends Enum<T>> extends Deserializer<T> {
private T victim;
@SuppressWarnings("unchecked")
public Serializer(T victim) {
super((Class<T>) victim.getClass());
this.victim = victim;
}
public void to(Intent intent) {
intent.putExtra(name, victim.ordinal());
}
}
public static class Deserializer<T extends Enum<T>> {
protected Class<T> victimType;
protected String name;
public Deserializer(Class<T> victimType) {
this.victimType = victimType;
this.name = victimType.getName();
}
public T from(Intent intent) {
if (!intent.hasExtra(name)) throw new IllegalStateException();
return victimType.getEnumConstants()[intent.getIntExtra(name, -1)];
}
}
public static <T extends Enum<T>> Deserializer<T> deserialize(Class<T> victim) {
return new Deserializer<T>(victim);
}
public static <T extends Enum<T>> Serializer<T> serialize(T victim) {
return new Serializer<T>(victim);
}
}
使用法:
// Sender usage
EnumUtil.serialize(AwesomeEnum.Something).to(intent);
// Receiver usage
AwesomeEnum result =
EnumUtil.deserialize(AwesomeEnum.class).from(intent);
オプション3(Kotlinを使用):
久しぶりにKotlinが登場してから、新しいパラダイムに別のオプションを追加するつもりでした。ここでは、拡張関数と具体化された型(コンパイル時に型を保持する)を利用できます。
inline fun <reified T : Enum<T>> Intent.putExtra(victim: T): Intent =
putExtra(T::class.java.name, victim.ordinal)
inline fun <reified T: Enum<T>> Intent.getEnumExtra(): T? =
getIntExtra(T::class.java.name, -1)
.takeUnless { it == -1 }
?.let { T::class.java.enumConstants[it] }
このようにすると、いくつかの利点があります。
- シリアル化を実行するために中間オブジェクトの「オーバーヘッド」を必要としません。
inlineこれは、呼び出しが関数内のコードに置き換えられるため、すべてが適切に行われるためです。
- これらの関数は、SDKの関数に類似しているため、より使い慣れています。
- IDEはこれらの関数をオートコンプリートします。つまり、ユーティリティクラスの事前の知識は必要ありません。
欠点の1つは、エミュムの順序を変更すると、古い参照が機能しなくなることです。保留中のインテント内のインテントのようなものは、更新を生き残る可能性があるため、これが問題になる可能性があります。ただし、それ以外の時間は問題ありません。
位置の代わりに名前を使用するなど、他のソリューションでも値の名前を変更すると失敗することに注意することが重要です。ただし、これらの場合、不正なEnum値の代わりに例外が発生します。
使用法:
// Sender usage
intent.putExtra(AwesomeEnum.SOMETHING)
// Receiver usage
val result = intent.getEnumExtra<AwesomeEnum>()