Ini adalah pertanyaan lama, tetapi semua orang gagal menyebutkan bahwa Enums sebenarnya Serializabledan karenanya dapat dengan sempurna ditambahkan ke Intent sebagai tambahan. Seperti ini:
public enum AwesomeEnum {
SOMETHING, OTHER;
}
intent.putExtra("AwesomeEnum", AwesomeEnum.SOMETHING);
AwesomeEnum result = (AwesomeEnum) intent.getSerializableExtra("AwesomeEnum");
Saran untuk menggunakan variabel statis atau aplikasi-lebar adalah ide yang sangat buruk. Ini benar-benar pasangan kegiatan Anda ke sistem pengelolaan negara, dan sulit untuk mempertahankan, men-debug dan terikat masalah.
ALTERNATIF:
Poin yang baik dicatat oleh tedzyc tentang fakta bahwa solusi diberikan oleh Oderik memberi Anda kesalahan. Namun, alternatif yang ditawarkan agak rumit untuk digunakan (bahkan menggunakan obat generik).
Jika Anda benar-benar khawatir tentang kinerja menambahkan enum ke Intent, saya mengusulkan alternatif ini sebagai gantinya:
PILIHAN 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)];
}
}
Pemakaian:
// Sender usage
AwesomeEnum.SOMETHING.attachTo(intent);
// Receiver usage
AwesomeEnum result = AwesomeEnum.detachFrom(intent);
PILIHAN 2:
(generik, dapat digunakan kembali, dan dipisahkan dari enum)
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);
}
}
Pemakaian:
// Sender usage
EnumUtil.serialize(AwesomeEnum.Something).to(intent);
// Receiver usage
AwesomeEnum result =
EnumUtil.deserialize(AwesomeEnum.class).from(intent);
OPSI 3 (dengan Kotlin):
Sudah lama, tapi karena sekarang kita memiliki Kotlin, saya pikir saya akan menambahkan opsi lain untuk paradigma baru. Di sini kita dapat menggunakan fungsi ekstensi dan tipe reified (yang mempertahankan tipe ketika kompilasi).
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] }
Ada beberapa manfaat melakukannya dengan cara ini.
- Kami tidak memerlukan "overhead" dari objek perantara untuk melakukan serialisasi karena semuanya dilakukan di tempat berkat
inline yang akan menggantikan panggilan dengan kode di dalam fungsi.
- Fungsinya lebih akrab karena mirip dengan yang SDK.
- IDE akan melengkapi fungsi-fungsi ini secara otomatis yang berarti tidak perlu memiliki pengetahuan sebelumnya tentang kelas utilitas.
Salah satu kelemahannya adalah bahwa, jika kita mengubah urutan Emum, maka referensi lama mana pun tidak akan berfungsi. Ini bisa menjadi masalah dengan hal-hal seperti Maksud di dalam maksud yang tertunda karena mereka dapat bertahan dari pembaruan. Namun, untuk sisa waktu, itu harus ok.
Penting untuk dicatat bahwa solusi lain, seperti menggunakan nama alih-alih posisi, juga akan gagal jika kita mengganti nama salah satu nilai. Meskipun, dalam kasus tersebut, kami mendapatkan pengecualian alih-alih nilai Enum yang salah.
Pemakaian:
// Sender usage
intent.putExtra(AwesomeEnum.SOMETHING)
// Receiver usage
val result = intent.getEnumExtra<AwesomeEnum>()