Dies ist eine alte Frage, aber jeder vergisst zu erwähnen, dass Enums eigentlich Serializable
und kann daher problemlos als Zusatz zu einem Vorhaben hinzugefügt werden. Zum Beispiel so:
public enum AwesomeEnum {
SOMETHING, OTHER;
}
intent.putExtra("AwesomeEnum", AwesomeEnum.SOMETHING);
AwesomeEnum result = (AwesomeEnum) intent.getSerializableExtra("AwesomeEnum");
Der Vorschlag, statische oder anwendungsweite Variablen zu verwenden, ist eine wirklich schlechte Idee. Dadurch werden Ihre Aktivitäten an ein zustandsverwaltendes System gekoppelt, und es ist schwer zu warten, zu debuggen und zu problematisieren.
ALTERNATIVEN:
Ein guter Punkt wurde angemerkt von tedzyc über die Tatsache, dass die Lösung, die von Oderik gibt eine Fehlermeldung aus. Die angebotene Alternative ist jedoch etwas umständlich in der Anwendung (selbst bei Verwendung von Generika).
Wenn Sie sich wirklich Sorgen um die Leistung des Hinzufügens des Enums zu einem Intent machen, schlage ich stattdessen diese Alternativen vor:
OPTION 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);
OPTION 2: (generisch, wiederverwendbar und vom Enum entkoppelt)
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);
OPTION 3 (mit Kotlin):
Es ist schon eine Weile her, aber da wir jetzt Kotlin haben, dachte ich, ich würde eine weitere Option für das neue Paradigma hinzufügen. Hier können wir Erweiterungsfunktionen und reifizierte Typen verwenden (die den Typ beim Kompilieren beibehalten).
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] }
Diese Vorgehensweise hat einige Vorteile.
- Wir benötigen nicht den "Overhead" eines zwischengeschalteten Objekts, um die Serialisierung durchzuführen, da dies alles dank der
inline
der die Aufrufe durch den Code innerhalb der Funktion ersetzt.
- Die Funktionen sind vertrauter, da sie den SDK-Funktionen ähnlich sind.
- Die IDE füllt diese Funktionen automatisch aus, d. h. es sind keine Vorkenntnisse über die Utility-Klasse erforderlich.
Einer der Nachteile ist, dass, wenn wir die Reihenfolge der Emums ändern, jede alte Referenz nicht mehr funktioniert. Dies kann ein Problem mit Dingen wie Intents innerhalb von anhängigen Intents sein, da sie Updates überleben können. Für den Rest der Zeit sollte es jedoch in Ordnung sein.
Es ist wichtig zu beachten, dass andere Lösungen, wie die Verwendung des Namens anstelle der Position, ebenfalls fehlschlagen, wenn wir einen der Werte umbenennen. Allerdings erhalten wir in diesen Fällen eine Ausnahme anstelle des falschen Enum-Werts.
使用方法
// Sender usage
intent.putExtra(AwesomeEnum.SOMETHING)
// Receiver usage
val result = intent.getEnumExtra<AwesomeEnum>()