Dies ist eine alte Frage, aber jeder erwähnt nicht, dass Enums tatsächlich sind Serializable
und daher perfekt zu einer Absicht als Extra hinzugefügt werden können. So was:
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. Dies koppelt Ihre Aktivitäten wirklich an ein Statusverwaltungssystem, und es ist schwierig, sie zu warten, zu debuggen und an Probleme zu binden.
ALTERNATIVEN:
Tedzyc hat einen guten Punkt in Bezug auf die Tatsache festgestellt , dass die von Oderik bereitgestellte Lösung einen Fehler liefert. Die angebotene Alternative ist jedoch etwas umständlich (auch bei Verwendung von Generika).
Wenn Sie sich wirklich Sorgen über die Leistung des Hinzufügens der Aufzählung zu einer Absicht 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)];
}
}
Verwendung:
// Sender usage
AwesomeEnum.SOMETHING.attachTo(intent);
// Receiver usage
AwesomeEnum result = AwesomeEnum.detachFrom(intent);
OPTION 2:
(generisch, wiederverwendbar und von der Aufzählung 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);
}
}
Verwendung:
// 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] }
Es gibt einige Vorteile, wenn Sie dies so tun.
- Wir benötigen nicht den "Overhead" eines Zwischenobjekts, um die Serialisierung durchzuführen, da alles an Ort und Stelle erfolgt,
inline
wodurch die Aufrufe durch den Code innerhalb der Funktion ersetzt werden.
- Die Funktionen sind vertrauter, da sie den SDK-Funktionen ähnlich sind.
- Die IDE vervollständigt diese Funktionen automatisch, sodass keine Vorkenntnisse der Utility-Klasse erforderlich sind.
Einer der Nachteile ist, dass, wenn wir die Reihenfolge der Emums ändern, eine alte Referenz nicht funktioniert. Dies kann ein Problem mit Dingen wie Absichten in ausstehenden Absichten sein, da diese Aktualisierungen ü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. In diesen Fällen erhalten wir jedoch eine Ausnahme anstelle des falschen Enum-Werts.
Verwendung:
// Sender usage
intent.putExtra(AwesomeEnum.SOMETHING)
// Receiver usage
val result = intent.getEnumExtra<AwesomeEnum>()