অ্যান্ড্রয়েড: একটি বান্ডেলে একটি এনাম রাখবেন কীভাবে?


332

আপনি কীভাবে কোনও এনড্রয়েড বান্ডলে কোনও এনাম অবজেক্ট যুক্ত করবেন?


11
আমার মতে গুগল কর্মীদের পরামর্শ খারাপ। এনামগুলি খুব সুবিধাজনক এবং বর্ণনা করা ওভারহেড পীড়িত suffering
অগনিয়ান

3
আপনি যদি উত্তরগুলি আবার দেখতে চান এবং দ্বিতীয়টি গ্রহণ করতে পারেন যদি আপনি মনে করেন এটি আরও ভাল পছন্দ হতে পারে।
ফিলিপ

6
উপরের লিঙ্কটিতে "এড়ানো এনিমস" শিরোনামের অধীনে এখন এটি এটি বলেছেন: পারফরম্যান্স মিথগুলি এই নথির পূর্ববর্তী সংস্করণগুলি বিভিন্ন বিভ্রান্তিমূলক দাবি করেছে made আমরা তাদের কয়েকটি এখানে সম্বোধন করি।
স্ট্যাক ওভারফ্লো

বিভাগটি এখন আর উপস্থিত নেই।
নাথানিয়েল ডি ওয়াগোনার

উত্তর:


726

এনামগুলি সিরিয়ালাইজযোগ্য তাই কোনও সমস্যা নেই।

নিম্নলিখিত এনাম দেওয়া:

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
আমি আপনার উত্তরের পক্ষে মতামত জানাতাম, তবে প্রশ্নটি ছিল একটি এনামকে একটি বান্ডিলের সাথে যুক্ত করার বিষয়ে এবং আপনার উত্তরটি কীভাবে একটি উদ্বেগের সাথে এটি যুক্ত করবেন তা ব্যাখ্যা করে ... তবে এটি ঠিক একই জিনিস, তবে নীচে আলেজান্দ্রো আপনার উত্তরটি স্থির করেছেন।
Pooks

2
এটি বান্ডিলের সাথে ব্যবহার করার সময়, এটি ছুড়ে দেয়ClassNotFoundException
প্রদর্শন করুন

2
এই সুপার ধীর হতে পারে এবং কিছু অ্যারে যে enum, ইত্যাদি দেখুন ধারণ আকার পরিবর্তন নেই stackoverflow.com/a/5551155/175156
yincrash

1
@ এনক্র্যাশ এনাম কাস্টম সিরিয়ালাইজেশন ব্যবহার করে যা বেশ দ্রুত। প্রুফ: ডকস.ওরাকল.com
জাভ্যাস

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/... , কাস্টম Enums serializable নয়। সুতরাং একটি এনুমে কাস্টম ক্ষেত্রগুলি সিরিয়ালযুক্ত হবে না। এটার সাথে তুমি কিভাবে চুক্তি করলে?
ক্লু

ভাল প্রশ্ন @ ক্লু! সম্ভবত তখন আপনার স্ট্যাকওভারফ্লো
আলেজান্দ্রো কলোরাডো

@ ক্লু কাস্টম ক্ষেত্রগুলি সিরিয়ালীকৃত হওয়ার আশা না করে। এটি ঠিক কাজ করে যদি উপরের কোডটির মতো এটি কেবল একটি সাধারণ এনাম।
ব্লুহল্লু

@ আলেজান্দ্রো কলোরাডো এটি মাইগেলের উত্তরগুলিতে কী যুক্ত করে?
tir38

1
মিগুয়েলের উত্তরটি ২০১৫ সালে সম্পাদিত হয়েছিল। মূল উত্তরটি বান্ডিল সম্পর্কে কিছুই বলেনি, এটি কেবল একটি অভিপ্রায়র উদাহরণ দেখিয়েছে।
আলেজান্দ্রো কলোরাডো

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
এটি একটি ভাল উত্তর, তবে এটি একটি এক্সটেনশন পদ্ধতির সাথে পরিপূরক হতে পারে, আমি এটি এখানে ব্যবহার করি: gist.github.com/Grohden/eea5ff9d5e3ba955aa2f57ff0df2683f
গ্যাব্রিয়েল দে অলিভিরা রোহডেন 23:58

.nameখুব গুরুত্বপূর্ণ পাথ
ফান ভ্যান লিনহ

এই বাঁক তুলনায় অনেক সহজ বলে মনে হয় Enum একটি parcelable, যা আরও জটিলতা তৈরি করবে যদি Android এর সঙ্গে কাজ মধ্যে কক্ষ ডাটাবেসের গ্রন্থাগার।
অ্যাডাম হুরউইৎজ

@ গ্যাব্রিয়েলডিওলিভেরারোডেন, আমি নিশ্চিত নই যে কেবলমাত্র .nameইন-এর ব্যবহার এড়ানো হবে বলে মনে হচ্ছে এটি সম্প্রসারণ পদ্ধতির প্রয়োজন putString()। কোটলিনের সাথে এটি ইতিমধ্যে ব্যবহার করা থাকলে স্রোতধারিত .applyউদাহরণস্বরূপ :ContentFragment.newInstance(Bundle().apply { putString(FEED_TYPE_KEY, SAVED.name) })
অ্যাডাম হুরউইৎজ

@ অ্যাডাম হারুইটস, প্রস্তাবিত এক্সটেনশনটি কি কোটলিন্স এক্সটেনশন ফাংশনের পুরো পয়েন্টটি কাজ করে না? এটি আপনাকে ভুল না করার জন্য বল প্রয়োগ করে, এটি নিখুঁত! @ গ্যাব্রিয়েলডিওলিভেরারোডেনের লিঙ্ক bundle.putEnum(key, enum) | bundle.getEnum<>(key)
ইয়োকিচ

17

এটিকে myEnumValue.name () থেকে স্ট্রিং হিসাবে পাস করা এবং এটি আপনারEnums.valueOf (গুলি) থেকে পুনরুদ্ধার করা ভাল, অন্যথায় এনামের ক্রম সংরক্ষণ করা আবশ্যক!

দীর্ঘতর ব্যাখ্যা: এনাম অর্ডিনাল থেকে এনাম টাইপে রূপান্তর করুন


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)), পার্সেবল বাস্তবায়ন এখানে অপ্রয়োজনীয় এবং অযৌক্তিক।
মিহা_এক্স 64

1
Parcelableএনাম-মানগুলির অ্যারে সঞ্চয় করার জন্য ব্যবহার করা ভাল সমাধান।
রোডনভি 500 500

2

বান্ডেল.পুটসারিয়ালাইজেবল (স্ট্রিং কী, সিরিয়ালাইজযোগ্য গুলি) এবং বান্ডেল.জেটসিরাইজিয়েবল (স্ট্রিং কী) ব্যবহার করুন:

enum Mode = {
  BASIC, ADVANCED
}

Mode m = Mode.BASIC;

bundle.putSerializable("mode", m);

...

Mode m;
m = bundle.getSerializable("mode");

ডকুমেন্টেশন: http://developer.android.com/references/android/os/Bundle.html


2

জন্য ইন্টেন্ট আপনি এভাবে ব্যবহার করতে পারেন:

অভিপ্রায়: কোটলিন

প্রথম কার্যকলাপ:

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{}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.