यह एक पुराना सवाल है, लेकिन हर कोई यह उल्लेख करने में विफल रहता है कि एनम वास्तव में हैं 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:
(सामान्य, पुन: प्रयोज्य और enum से decoupled)
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जो फ़ंक्शन के अंदर कोड के साथ कॉल को बदल देगा।
- फ़ंक्शन अधिक परिचित हैं क्योंकि वे एसडीके वाले के समान हैं।
- आईडीई इन कार्यों को स्वत: पूर्ण करेगा जिसका अर्थ है कि उपयोगिता वर्ग के पिछले ज्ञान की आवश्यकता नहीं है।
डाउनसाइड्स में से एक यह है कि, यदि हम एम्स के क्रम को बदलते हैं, तो कोई भी पुराना संदर्भ काम नहीं करेगा। यह लंबित इरादों के अंदर इरादों जैसी चीजों के साथ एक मुद्दा हो सकता है क्योंकि वे अपडेट से बच सकते हैं। हालांकि, बाकी समय के लिए, यह ठीक होना चाहिए।
यह ध्यान रखना महत्वपूर्ण है कि स्थिति के बजाय नाम का उपयोग करने जैसे अन्य समाधान भी विफल हो जाएंगे यदि हम किसी भी मूल्य का नाम बदलते हैं। हालाँकि, उन मामलों में, हमें गलत Enum मान के बजाय एक अपवाद मिलता है।
उपयोग:
// Sender usage
intent.putExtra(AwesomeEnum.SOMETHING)
// Receiver usage
val result = intent.getEnumExtra<AwesomeEnum>()