我有一个活动,启动时需要访问两个不同的数组列表。两个列表都是我自己创建的不同对象。
基本上,我需要一种方法来将这些对象从Intent传递给活动。我可以使用addExtras(),但这需要一个Parceable兼容类。我可以使我的类传递序列化,但据我所知,这减慢了程序。
我有什么选择?
我可以传递一个Enum吗?
题外话:有没有一种方法可以将参数从Intent传递给Activity构造函数?
我有一个活动,启动时需要访问两个不同的数组列表。两个列表都是我自己创建的不同对象。
基本上,我需要一种方法来将这些对象从Intent传递给活动。我可以使用addExtras(),但这需要一个Parceable兼容类。我可以使我的类传递序列化,但据我所知,这减慢了程序。
我有什么选择?
我可以传递一个Enum吗?
题外话:有没有一种方法可以将参数从Intent传递给Activity构造函数?
当前回答
我喜欢简单。
The Fred activity has two modes -- HAPPY and SAD. Create a static IntentFactory that creates your Intent for you. Pass it the Mode you want. The IntentFactory uses the name of the Mode class as the name of the extra. The IntentFactory converts the Mode to a String using name() Upon entry into onCreate use this info to convert back to a Mode. You could use ordinal() and Mode.values() as well. I like strings because I can see them in the debugger. public class Fred extends Activity { public static enum Mode { HAPPY, SAD, ; } public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.betting); Intent intent = getIntent(); Mode mode = Mode.valueOf(getIntent().getStringExtra(Mode.class.getName())); Toast.makeText(this, "mode="+mode.toString(), Toast.LENGTH_LONG).show(); } public static Intent IntentFactory(Context context, Mode mode){ Intent intent = new Intent(); intent.setClass(context,Fred.class); intent.putExtra(Mode.class.getName(),mode.name()); return intent; } }
其他回答
考虑以下enum::
public static enum MyEnum {
ValueA,
ValueB
}
对于通过::
Intent mainIntent = new Intent(this,MyActivity.class);
mainIntent.putExtra("ENUM_CONST", MyEnum.ValueA);
this.startActivity(mainIntent);
从intent/bundle/arguments中返回:
MyEnum myEnum = (MyEnum) intent.getSerializableExtra("ENUM_CONST");
你可以让你的枚举实现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];
致以最亲切的问候。 :)
关于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));
使用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>()