我有一个活动,启动时需要访问两个不同的数组列表。两个列表都是我自己创建的不同对象。
基本上,我需要一种方法来将这些对象从Intent传递给活动。我可以使用addExtras(),但这需要一个Parceable兼容类。我可以使我的类传递序列化,但据我所知,这减慢了程序。
我有什么选择?
我可以传递一个Enum吗?
题外话:有没有一种方法可以将参数从Intent传递给Activity构造函数?
我有一个活动,启动时需要访问两个不同的数组列表。两个列表都是我自己创建的不同对象。
基本上,我需要一种方法来将这些对象从Intent传递给活动。我可以使用addExtras(),但这需要一个Parceable兼容类。我可以使我的类传递序列化,但据我所知,这减慢了程序。
我有什么选择?
我可以传递一个Enum吗?
题外话:有没有一种方法可以将参数从Intent传递给Activity构造函数?
当前回答
你可以让你的枚举实现Parcelable,这对枚举来说非常简单:
public enum MyEnum implements Parcelable {
VALUE;
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(final Parcel dest, final int flags) {
dest.writeInt(ordinal());
}
public static final Creator<MyEnum> CREATOR = new Creator<MyEnum>() {
@Override
public MyEnum createFromParcel(final Parcel source) {
return MyEnum.values()[source.readInt()];
}
@Override
public MyEnum[] newArray(final int size) {
return new MyEnum[size];
}
};
}
然后你可以使用Intent。Parcelable putExtra(字符串)。
更新:请注意沉船的评论,枚举.values()分配一个新的数组在每次调用。
更新:Android Studio提供了一个实时模板ParcelableEnum来实现这个解决方案。(在Windows上,使用Ctrl+J)
其他回答
要按意图传递枚举,可以将enum转换为整数。
Ex:
public enum Num{A ,B}
发送(enum to integer):
Num send = Num.A;
intent.putExtra("TEST", send.ordinal());
接收(整数到enum):
Num rev;
int temp = intent.getIntExtra("TEST", -1);
if(temp >= 0 && temp < Num.values().length)
rev = Num.values()[temp];
致以最亲切的问候。 :)
使用Kotlin扩展函数
inline fun <reified T : Enum<T>> Intent.putExtra(enumVal: T, key: String? = T::class.qualifiedName): Intent =
putExtra(key, enumVal.ordinal)
inline fun <reified T: Enum<T>> Intent.getEnumExtra(key: String? = T::class.qualifiedName): T? =
getIntExtra(key, -1)
.takeUnless { it == -1 }
?.let { T::class.java.enumConstants[it] }
这使您可以灵活地传递多个相同的枚举类型,或者默认使用类名。
// Add to gradle
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
// Import the extension functions
import path.to.my.kotlin.script.putExtra
import path.to.my.kotlin.script.getEnumExtra
// To Send
intent.putExtra(MyEnumClass.VALUE)
// To Receive
val result = intent.getEnumExtra<MyEnumClass>()
它可以使你的Enum实现Serializable,然后你可以通过Intent传递它,因为有一个方法可以将它作为一个Serializable传递。使用int而不是enum的建议是错误的。枚举用于使代码更易于阅读和维护。如果不能使用枚举,这将是倒退到黑暗时代的一大步。
关于Oderik的帖子:
你可以让你的枚举实现Parcelable,这对枚举来说非常简单: MyEnum实现Parcelable { ... } 你可以使用Intent。Parcelable putExtra(字符串)。
如果你定义了MyEnum变量MyEnum,那么执行intent。putExtra("Parcelable1", myEnum),你会得到一个"方法putExtra(String, Parcelable)是模棱两可的类型意图"错误消息。 因为还有一个意图。putExtra(String, Parcelable)方法,和原来的'Enum'类型本身实现了Serializable接口,所以编译器不知道选择哪个方法(意图。putExtra(String, Parcelable/or Serializable))。
建议从MyEnum中删除Parcelable接口,并将核心代码移动到wrap类的Parcelable实现中,就像这样(Father2是一个Parcelable,包含一个enum字段):
public class Father2 implements Parcelable {
AnotherEnum mAnotherEnum;
int mField;
public Father2(AnotherEnum myEnum, int field) {
mAnotherEnum = myEnum;
mField = field;
}
private Father2(Parcel in) {
mField = in.readInt();
mAnotherEnum = AnotherEnum.values()[in.readInt()];
}
public static final Parcelable.Creator<Father2> CREATOR = new Parcelable.Creator<Father2>() {
public Father2 createFromParcel(Parcel in) {
return new Father2(in);
}
@Override
public Father2[] newArray(int size) {
return new Father2[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mField);
dest.writeInt(mAnotherEnum.ordinal());
}
}
然后我们可以做:
AnotherEnum anotherEnum = AnotherEnum.Z;
intent.putExtra("Serializable2", AnotherEnum.X);
intent.putExtra("Parcelable2", new Father2(AnotherEnum.X, 7));
你可以使用枚举构造函数为enum设置基本数据类型。
public enum DaysOfWeek {
MONDAY(1),
TUESDAY(2),
WEDNESDAY(3),
THURSDAY(4),
FRIDAY(5),
SATURDAY(6),
SUNDAY(7);
private int value;
private DaysOfWeek(int value) {
this.value = value;
}
public int getValue() {
return this.value;
}
private static final SparseArray<DaysOfWeek> map = new SparseArray<DaysOfWeek>();
static
{
for (DaysOfWeek daysOfWeek : DaysOfWeek.values())
map.put(daysOfWeek.value, daysOfWeek);
}
public static DaysOfWeek from(int value) {
return map.get(value);
}
}
你可以使用传递int作为额外参数,然后使用它的值从enum中取出它。