Bu eski bir sorudur, ancak herkes Enum'ların aslında Serializableve dolayısıyla bir Niyet'e ekstra olarak mükemmel bir şekilde eklenebileceğinden bahsetmez . Bunun gibi:
public enum AwesomeEnum {
SOMETHING, OTHER;
}
intent.putExtra("AwesomeEnum", AwesomeEnum.SOMETHING);
AwesomeEnum result = (AwesomeEnum) intent.getSerializableExtra("AwesomeEnum");
Statik veya uygulama geneli değişkenlerin kullanılması önerisi gerçekten kötü bir fikirdir. Bu, faaliyetlerinizi gerçekten bir devlet yönetim sistemine bağlar ve bakımı, hata ayıklaması ve sorunla bağlanması zordur.
ALTERNATİFLERİ:
Tedzyc tarafından Oderik tarafından sağlanan çözümün size bir hata verdiği konusunda iyi bir noktaya dikkat çekildi . Bununla birlikte, sunulan alternatif kullanımı biraz hantaldır (jenerik ilaç kullanarak bile).
Eğer bir Niyet'e enum eklemenin performansından gerçekten endişeleniyorsanız bunun yerine şu alternatifleri öneriyorum:
SEÇENEK 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)];
}
}
Kullanımı:
// Sender usage
AwesomeEnum.SOMETHING.attachTo(intent);
// Receiver usage
AwesomeEnum result = AwesomeEnum.detachFrom(intent);
SEÇENEK 2:
(jenerik, tekrar kullanılabilir ve numaralandırmadan ayrılmıştır)
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);
}
}
Kullanımı:
// Sender usage
EnumUtil.serialize(AwesomeEnum.Something).to(intent);
// Receiver usage
AwesomeEnum result =
EnumUtil.deserialize(AwesomeEnum.class).from(intent);
SEÇENEK 3 (Kotlin ile):
Bir süre oldu, ama şimdi Kotlin'e sahibiz, yeni paradigma için başka bir seçenek ekleyeceğimi düşündüm. Burada eklenti işlevlerini ve birleştirilmiş türleri (derlerken türü koruyan) kullanabiliriz.
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] }
Bu şekilde yapmanın birkaç faydası vardır.
- Serileştirmeyi yapmak için ara nesnenin "tepegözünü" gerektirmez, çünkü tüm
inlinefonksiyonlar yerine çağrıları işlev içindeki kodla değiştirir.
- İşlevler SDK'lara benzer olduklarından daha tanıdıktır.
- IDE bu işlevleri otomatik olarak tamamlayacaktır, bu da yardımcı program sınıfı hakkında önceden bilgi sahibi olmanıza gerek olmadığı anlamına gelir.
Dezavantajlardan biri, Emumların sırasını değiştirirsek, eski referansların işe yaramayacağıdır. Bu, güncellemelerden kurtulabildikleri için bekleyen hedefler içindeki Hedefler gibi bir sorun olabilir. Ancak, zamanın geri kalanı için, tamam olmalıdır.
Değerlerden herhangi birini yeniden adlandırırsak, konum yerine adı kullanmak gibi diğer çözümlerin de başarısız olacağını unutmayın. Bununla birlikte, bu durumlarda, yanlış Enum değeri yerine bir istisna alırız.
Kullanımı:
// Sender usage
intent.putExtra(AwesomeEnum.SOMETHING)
// Receiver usage
val result = intent.getEnumExtra<AwesomeEnum>()