Це давнє запитання, але всі не зазначають, що "Енумс" насправді є, Serializableі тому він цілком може бути доданий до наміру як додаткового. Подобається це:
public enum AwesomeEnum {
SOMETHING, OTHER;
}
intent.putExtra("AwesomeEnum", AwesomeEnum.SOMETHING);
AwesomeEnum result = (AwesomeEnum) intent.getSerializableExtra("AwesomeEnum");
Пропозиція використовувати статичні чи загальноприйняті змінні - це дійсно погана ідея. Це дійсно поєднує вашу діяльність із системою управління державою, і її важко підтримувати, налагоджувати та вирішувати проблеми.
АЛЬТЕРНАТИВИ:
Добрий момент відмітив 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 (з Котліном):
Минув деякий час, але оскільки у нас є Котлін, я думав, що додам ще один варіант нової парадигми. Тут ми можемо скористатися функціями розширення та зміненими типами (що зберігає тип при компілюванні).
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 автоматично виконає ці функції, а це означає, що немає необхідності мати попередні знання про клас утиліти.
Одним із недоліків є те, що якщо ми змінимо порядок емусів, то будь-яка стара посилання не спрацює. Це може бути проблемою з такими речами, як "Інтенти" всередині відкладених намірів, оскільки вони можуть пережити оновлення. Однак решту часу це повинно бути нормально.
Важливо зазначити, що інші рішення, як-от використання імені замість позиції, також не вдасться, якщо ми перейменуємо будь-яке значення. Хоча в цих випадках ми отримуємо виняток замість неправильного значення Enum.
Використання:
// Sender usage
intent.putExtra(AwesomeEnum.SOMETHING)
// Receiver usage
val result = intent.getEnumExtra<AwesomeEnum>()