Làm thế nào để bạn thêm một đối tượng Enum vào Gói Android?
Làm thế nào để bạn thêm một đối tượng Enum vào Gói Android?
Câu trả lời:
Enums là serializable nên không có vấn đề.
Cho enum sau:
enum YourEnum {
TYPE1,
TYPE2
}
Gói:
// put
bundle.putSerializable("key", YourEnum.TYPE1);
// get
YourEnum yourenum = (YourEnum) bundle.get("key");
Ý định:
// put
intent.putExtra("key", yourEnum);
// get
yourEnum = (YourEnum) intent.getSerializableExtra("key");
outState.putSerializable("trollData", game.getFunkyTrolls());
đang tải : game.setFunkyTrolls((Game.FunkyTroll[]) savedInstanceState.getSerializable("trollData"));
?
ClassNotFoundException
Tôi biết đây là một câu hỏi cũ, nhưng tôi đã gặp vấn đề tương tự và tôi muốn chia sẻ cách tôi giải quyết nó. Điều quan trọng là những gì Miguel nói: Enums là serializable.
Cho enum sau:
enum YourEnumType {
ENUM_KEY_1,
ENUM_KEY_2
}
Đặt:
Bundle args = new Bundle();
args.putSerializable("arg", YourEnumType.ENUM_KEY_1);
Để hoàn thiện hơn, đây là một ví dụ đầy đủ về cách đưa vào và lấy lại một enum từ một gói.
Cho enum sau:
enum EnumType{
ENUM_VALUE_1,
ENUM_VALUE_2
}
Bạn có thể đặt enum vào một gói:
bundle.putSerializable("enum_key", EnumType.ENUM_VALUE_1);
Và lấy lại enum:
EnumType enumType = (EnumType)bundle.getSerializable("enum_key");
Tôi sử dụng kotlin.
companion object {
enum class Mode {
MODE_REFERENCE,
MODE_DOWNLOAD
}
}
sau đó đưa vào Ý định:
intent.putExtra(KEY_MODE, Mode.MODE_DOWNLOAD.name)
khi bạn nhận được giá trị:
mode = Mode.valueOf(intent.getStringExtra(KEY_MODE))
.name
là con đường rất quan trọng
.name
trong putString()
. Với Kotlin, nó đã được sắp xếp hợp lý nếu sử dụng .apply
. Ví dụ :ContentFragment.newInstance(Bundle().apply { putString(FEED_TYPE_KEY, SAVED.name) })
bundle.putEnum(key, enum) | bundle.getEnum<>(key)
Có thể tốt hơn để chuyển nó dưới dạng chuỗi từ myEnumValue.name () và khôi phục nó từ YourEnums.valueOf (s), vì nếu không thì lệnh của enum phải được giữ nguyên!
Giải thích dài hơn: Chuyển đổi từ enum ordinal sang enum type
Một lựa chọn khác:
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());
}
}
putSerializable(key, value)
/ (Type) getSerializable(key)
hoặc putString(key, value.name())
/ Type.valueOf(getString(key))
, triển khai Parcelable ở đây là dự phòng và vô nghĩa.
Parcelable
là một giải pháp tốt để lưu trữ Mảng giá trị Enum.
Sử dụng bundle.putSerializable (Khóa chuỗi, sê-ri hóa) và bundle.getSerializable (Khóa chuỗi):
enum Mode = {
BASIC, ADVANCED
}
Mode m = Mode.BASIC;
bundle.putSerializable("mode", m);
...
Mode m;
m = bundle.getSerializable("mode");
Tài liệu: http://developer.android.com/reference/android/os/Bundle.html
Đối với ý định, bạn có thể sử dụng cách này:
Ý định: kotlin
Hoạt động đầu tiên:
val intent = Intent(context, SecondActivity::class.java)
intent.putExtra("type", typeEnum.A)
startActivity(intent)
Hoạt động thứ hai:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//...
val type = (intent.extras?.get("type") as? typeEnum.Type?)
}
Một điều cần phải nhận thức được - nếu bạn đang sử dụng bundle.putSerializable
cho một Bundle
để được thêm vào một thông báo, bạn có thể chạy vào các vấn đề sau đây:
*** Uncaught remote exception! (Exceptions are not yet supported across processes.)
java.lang.RuntimeException: Parcelable encountered ClassNotFoundException reading a Serializable object.
...
Để giải quyết vấn đề này, bạn có thể làm như sau:
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);
}
}
}
Mà sau đó có thể được sử dụng như vậy:
// Put
Bundle bundle = new Bundle();
bundle.putInt("key", MyEnum.TYPE_0.getCode());
// Get
MyEnum myEnum = MyEnum.fromCode(bundle.getInt("key"));
Một cách đơn giản, gán giá trị nguyên cho enum
Xem ví dụ sau:
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;
}
}
Phía người gửi:
Intent nextIntent = new Intent(CurrentActivity.this, NextActivity.class);
nextIntent.putExtra("key_type", MyEnum.TYPE_ONE.getValue());
startActivity(nextIntent);
Bên nhận:
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();
Tôi nghĩ chuyển đổi enum thành int (đối với enum bình thường) và sau đó thiết lập gói là cách dễ nhất. thích mã này cho ý định:
myIntent.PutExtra("Side", (int)PageType.Fornt);
sau đó cho trạng thái kiểm tra:
int type = Intent.GetIntExtra("Side",-1);
if(type == (int)PageType.Fornt)
{
//To Do
}
nhưng không làm việc cho tất cả các loại enum!
Tôi đã tạo tiện ích mở rộng Koltin:
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) )
}
Tạo một gói và thêm:
Bundle().also {
it.putEnum( "KEY" , ENUM_CLAS.ITEM )
}
và lấy:
intent?.getEnumExtra< ENUM_CLAS >( "KEY" )?.let{}