Android: एक बंडल में एनम कैसे डालें?


332

एंड्रॉइड बंडल में आप एनम ऑब्जेक्ट कैसे जोड़ते हैं?


11
मेरी राय में Google कर्मचारियों की सलाह खराब है। एनम बहुत सुविधाजनक हैं और वर्णित ओवरहेड पीड़ित हैं।
संज्ञी जूल

3
क्या आप उत्तर को फिर से देख सकते हैं और 2 को स्वीकार कर सकते हैं यदि आपको लगता है कि यह एक बेहतर विकल्प हो सकता है।
फिलिप

6
उपरोक्त लिंक में शीर्षक "बचने वाले Enums" के तहत अब यह कहता है: इस दस्तावेज़ के प्रदर्शन मिथक पिछले संस्करणों ने कई भ्रामक दावे किए। हम उनमें से कुछ को यहां संबोधित करते हैं।
स्टैकऑवरफ्लो 11

वह खंड अब भी मौजूद नहीं है।
नथानिएल डी। वैगनर

जवाबों:


726

Enums Serializable हैं इसलिए कोई समस्या नहीं है।

निम्नलिखित एनम को देखते हुए:

enum YourEnum {
  TYPE1,
  TYPE2
}

बंडल:

// put
bundle.putSerializable("key", YourEnum.TYPE1);

// get 
YourEnum yourenum = (YourEnum) bundle.get("key");

आशय:

// put
intent.putExtra("key", yourEnum);

// get
yourEnum = (YourEnum) intent.getSerializableExtra("key");

क्या इस पद्धति में कुछ गड़बड़ है: बचत: outState.putSerializable("trollData", game.getFunkyTrolls());लोडिंग game.setFunkyTrolls((Game.FunkyTroll[]) savedInstanceState.getSerializable("trollData"));:?
मोबर्ग

21
मैंने आपके उत्तर के लिए मतदान किया होगा, लेकिन सवाल एनम को एक बंडल में जोड़ने के बारे में था और आपका उत्तर बताता है कि इसे एक आशय में कैसे जोड़ा जाए ... दी गई यह लगभग एक ही बात है, लेकिन एलेजांद्रो ने नीचे आपके उत्तर को निर्धारित किया।
बजे

2
बंडल के साथ इसका उपयोग करते समय, यह फेंकता हैClassNotFoundException
प्रदर्शन नाम

2
यह सुपर स्लो हो सकता है और उन चीजों के सरणियों को स्केल नहीं करता है जिनमें
एनम

1
@yincrash enum कस्टम क्रमांकन का उपयोग करता है जो काफी तेज़ है। प्रमाण: docs.oracle.com/javase/1.5.0/docs/guide/serialization/spec/…
Miha_x64

164

मुझे पता है कि यह एक पुराना सवाल है, लेकिन मैं इसी समस्या के साथ आया हूं और मैं इसे साझा करना चाहूंगा कि मैंने इसे कैसे हल किया। मिगुएल ने कहा कि कुंजी है: एनमेस सीरियल्सिबल हैं।

निम्नलिखित एनम को देखते हुए:

enum YourEnumType {
    ENUM_KEY_1, 
    ENUM_KEY_2
}

डाल:

Bundle args = new Bundle();
args.putSerializable("arg", YourEnumType.ENUM_KEY_1);

3
इसके आधार पर: stackoverflow.com/questions/15521309/… , कस्टम एनम क्रमबद्ध नहीं हैं। तो एक Enum में कस्टम फ़ील्ड क्रमबद्ध नहीं किया जाएगा। आप इस के साथ कैसे पेश आएंगे?
क्लू

अच्छा सवाल @clu! शायद तब आपको इसे एक स्ट्रिंग के रूप में पारित करने के बारे में सोचना चाहिए जैसा कि stackoverflow.com/questions/609860/…
एलेजांद्रो कोलोराडो

@clu सीरियल फ़ील्ड होने की उम्मीद नहीं करके। यह ठीक काम करता है अगर इसके ऊपर के कोड की तरह एक सामान्य एनम है।
ब्लूहल्लू

@ एलेजैंड्रो कैलोराडो यह मिगुएल के जवाब में क्या जोड़ता है?
tir38

1
मिगुएल का उत्तर 2015 को संपादित किया गया था। मूल उत्तर में बंडलों के बारे में कुछ नहीं कहा गया था, यह केवल एक इरादे का एक उदाहरण दिखा।
एलेजांद्रो कोलोराडो

41

संपूर्णता के लिए, यह एक पूर्ण उदाहरण है कि कैसे एक बंडल में डाल दिया जाए और एक एनम को वापस लाया जाए।

निम्नलिखित एनम को देखते हुए:

enum EnumType{
    ENUM_VALUE_1,
    ENUM_VALUE_2
}

आप एनाम को एक बंडल में रख सकते हैं:

bundle.putSerializable("enum_key", EnumType.ENUM_VALUE_1);

और एनम को वापस पाएं:

EnumType enumType = (EnumType)bundle.getSerializable("enum_key");

32

मैं कोटलिन का उपयोग करता हूं।

companion object {

        enum class Mode {
            MODE_REFERENCE,
            MODE_DOWNLOAD
        }
}

फिर इरादे में डाल दिया:

intent.putExtra(KEY_MODE, Mode.MODE_DOWNLOAD.name)

जब आप मूल्य पाने के लिए नेट करते हैं:

mode = Mode.valueOf(intent.getStringExtra(KEY_MODE))

6
यह एक अच्छा उत्तर है, लेकिन इसे एक विस्तार विधि के साथ पूरक किया जा सकता है, मैं यहां इसका उपयोग करता हूं
गेब्रियल डे ओलिवेरा

.nameबहुत महत्वपूर्ण पथ है
फान वान

इस मोड़ तुलना में बहुत सरल लगता है Enum एक parcelable है, जो आगे जटिलता पैदा करेगा अगर Android के साथ काम करने में कमरे का डेटाबेस पुस्तकालय।
एडम हर्विट्ज़

@GabrielDeOliveiraRohden, मुझे यकीन नहीं है कि विस्तार विधि की आवश्यकता है क्योंकि यह केवल अंदर के उपयोग से बचने के लिए लगता .nameहै putString()। कोटलिन के साथ अगर यह पहले से ही सुव्यवस्थित है .applyउदाहरण के लिए :ContentFragment.newInstance(Bundle().apply { putString(FEED_TYPE_KEY, SAVED.name) })
एडम हर्विट्ज

@AdamHurwitz, प्रस्तावित विस्तार से कोटालिंस के विस्तार कार्यों के पूरे बिंदु नहीं हैं? यह आपको गलतियाँ न करने के लिए प्रेरित करता है, यह बिल्कुल सही है! bundle.putEnum(key, enum) | bundle.getEnum<>(key)
@GabrielDeOliveiraRohden की

17

इसे myEnumValue.name () से स्ट्रिंग के रूप में पास करना और इसे YourEnums.valueOf (s) से पुनर्स्थापित करना बेहतर हो सकता है, क्योंकि अन्यथा एनम के आदेश को संरक्षित किया जाना चाहिए!

लंबी व्याख्या: एनम ऑर्डिनल से एनम टाइप में कनवर्ट करें


1
क्रमबद्धता से कोई फर्क नहीं पड़ता अगर क्रमांकन-> डिसेरिएलाइज़ेशन रनटाइम पर तुरंत होता है, जैसे कि एक गतिविधि से दूसरी गतिविधि पर कॉल करते समय। यह ऐप के पुराने संस्करणों में एक ऐप से इंटेंट्स भेजने जैसी प्रक्रियाओं में एक समस्या हो सकती है।
मिगेल

6

एक अन्य विकल्प:

public enum DataType implements Parcleable {
    SIMPLE, COMPLEX;

    public static final Parcelable.Creator<DataType> CREATOR = new Creator<DataType>() {

        @Override
        public DataType[] newArray(int size) {
            return new DataType[size];
        }

        @Override
        public DataType createFromParcel(Parcel source) {
            return DataType.values()[source.readInt()];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(this.ordinal());
    }
}

1
आप या तो putSerializable(key, value)/ (Type) getSerializable(key)या putString(key, value.name())/ का उपयोग कर सकते हैं Type.valueOf(getString(key)), यहाँ पार्सल लागू निरर्थक और निरर्थक है।
Miha_x64

1
Parcelableएनरम-मानों के एरे को संग्रहीत करने के लिए उपयोग करना एक अच्छा समाधान है।
रोडनव ५५००


2

के लिए आशय आप इस तरह से उपयोग कर सकते हैं:

आशय: कोटलिन

FirstActivity:

val intent = Intent(context, SecondActivity::class.java)
intent.putExtra("type", typeEnum.A)
startActivity(intent)

SecondActivity:

override fun onCreate(savedInstanceState: Bundle?) {
     super.onCreate(savedInstanceState) 
     //...
     val type = (intent.extras?.get("type") as? typeEnum.Type?)
}

1

एक बात का ध्यान रखें - यदि आप नोटिफिकेशन में शामिल होने के bundle.putSerializableलिए उपयोग कर रहे हैं Bundle, तो आप निम्नलिखित मुद्दे पर चल सकते हैं:

*** Uncaught remote exception!  (Exceptions are not yet supported across processes.)
    java.lang.RuntimeException: Parcelable encountered ClassNotFoundException reading a Serializable object.

...

इसके आसपास जाने के लिए, आप निम्नलिखित कार्य कर सकते हैं:

public enum MyEnum {
    TYPE_0(0),
    TYPE_1(1),
    TYPE_2(2);

    private final int code;

    private MyEnum(int code) {
        this.code = navigationOptionLabelResId;
    }

    public int getCode() {
        return code;
    }

    public static MyEnum fromCode(int code) {
        switch(code) {
            case 0:
                return TYPE_0;
            case 1:
                return TYPE_1;
            case 2:
                return TYPE_2;
            default:
                throw new RuntimeException(
                    "Illegal TYPE_0: " + code);
        }
    }
}

जो तब इस तरह इस्तेमाल किया जा सकता है:

// Put
Bundle bundle = new Bundle();
bundle.putInt("key", MyEnum.TYPE_0.getCode());

// Get 
MyEnum myEnum = MyEnum.fromCode(bundle.getInt("key"));

0

एक सरल तरीका है, एनमर को पूर्णांक मान प्रदान करें

निम्नलिखित उदाहरण देखें:

public enum MyEnum {

    TYPE_ONE(1), TYPE_TWO(2), TYPE_THREE(3);

    private int value;

    MyEnum(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

}

प्रेषक पक्ष:

Intent nextIntent = new Intent(CurrentActivity.this, NextActivity.class);
nextIntent.putExtra("key_type", MyEnum.TYPE_ONE.getValue());
startActivity(nextIntent);

रिसीवर पक्ष:

Bundle mExtras = getIntent().getExtras();
int mType = 0;
if (mExtras != null) {
    mType = mExtras.getInt("key_type", 0);
}

/* OR
    Intent mIntent = getIntent();
    int mType = mIntent.getIntExtra("key_type", 0);
*/

if(mType == MyEnum.TYPE_ONE.getValue())
    Toast.makeText(NextActivity.this, "TypeOne", Toast.LENGTH_SHORT).show();
else if(mType == MyEnum.TYPE_TWO.getValue())
    Toast.makeText(NextActivity.this, "TypeTwo", Toast.LENGTH_SHORT).show();
else if(mType == MyEnum.TYPE_THREE.getValue())
    Toast.makeText(NextActivity.this, "TypeThree", Toast.LENGTH_SHORT).show();
else
    Toast.makeText(NextActivity.this, "Wrong Key", Toast.LENGTH_SHORT).show();

0

मुझे लगता है कि एनम को इंट (सामान्य एनम के लिए) में परिवर्तित करें और फिर बंडल पर सेट करना सबसे आसान तरीका था। इस कोड को इरादे के लिए पसंद करें:

myIntent.PutExtra("Side", (int)PageType.Fornt);

फिर चेक स्टेट के लिए:

int type = Intent.GetIntExtra("Side",-1);
if(type == (int)PageType.Fornt)
{
    //To Do
}

लेकिन सभी एनम प्रकार के लिए काम नहीं!


0

मैंने कोल्टिन एक्सटेंशन बनाया है:

fun Bundle.putEnum(key: String, enum: Enum<*>) {
    this.putString( key , enum.name )
}

inline fun <reified T: Enum<T>> Intent.getEnumExtra(key:String) : T {
    return enumValueOf( getStringExtra(key) )
}

एक बंडल बनाएं और जोड़ें:

Bundle().also {
   it.putEnum( "KEY" , ENUM_CLAS.ITEM )
}

और पाओ:

intent?.getEnumExtra< ENUM_CLAS >( "KEY" )?.let{}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.