我有一个活动,启动时需要访问两个不同的ArrayLists.两个列表都是我自己创建的不同对象.
基本上我需要一种方法将这些对象从Intent传递给活动.我可以使用addExtras()但这需要一个Parceable兼容类.我可以让我的类通过序列化,但据我所知,这会减慢程序的速度.
我有什么选择?
我可以通过枚举吗?
旁白:有没有办法从Intent将参数传递给Activity Constructor?
pab*_*sco 527
这是一个古老的问题,但每个人都没有提到Enums实际上是Serializable因此可以完美地添加到Intent作为额外的.像这样:
public enum AwesomeEnum {
SOMETHING, OTHER;
}
intent.putExtra("AwesomeEnum", AwesomeEnum.SOMETHING);
AwesomeEnum result = (AwesomeEnum) intent.getSerializableExtra("AwesomeEnum");
Run Code Online (Sandbox Code Playgroud)
使用静态或应用程序范围变量的建议是一个非常糟糕的主意.这确实将您的活动与状态管理系统结合在一起,很难维护,调试和解决问题.
备择方案:
好点的是由著名tedzyc的事实,所提供的解决方案Oderik给你一个错误.然而,提供的替代方案有点崩溃 - 一些使用(甚至使用泛型).
如果您真的担心将枚举添加到意图中的表现,我建议使用这些替代方案:
选项1:
public enum AwesomeEnum {
SOMETHING, OTHER;
private static final String name = AwesomeEnum.class.getName();
public void attachTo(Intent intent) {
intent.putExtra(name, ordinal());
}
public static AwesomeEnum detachFrom(Intent intent) {
if(!intent.hasExtra(name)) throw new IllegalStateException();
return values()[intent.getIntExtra(name, -1)];
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
// Sender usage
AwesomeEnum.SOMETHING.attachTo(intent);
// Receiver usage
AwesomeEnum result = AwesomeEnum.detachFrom(intent);
Run Code Online (Sandbox Code Playgroud)
选项2 :( 通用,可重用和与枚举分离)
public final class EnumUtil {
public static class Serializer<T extends Enum<T>> extends Deserializer<T> {
private T victim;
@SuppressWarnings("unchecked")
public Serializer(T victim) {
super((Class<T>) victim.getClass());
this.victim = victim;
}
public void to(Intent intent) {
intent.putExtra(name, victim.ordinal());
}
}
public static class Deserializer<T extends Enum<T>> {
protected Class<T> victimType;
protected String name;
public Deserializer(Class<T> victimType) {
this.victimType = victimType;
this.name = victimType.getName();
}
public T from(Intent intent) {
if (!intent.hasExtra(name)) throw new IllegalStateException();
return victimType.getEnumConstants()[intent.getIntExtra(name, -1)];
}
}
public static <T extends Enum<T>> Deserializer<T> deserialize(Class<T> victim) {
return new Deserializer<T>(victim);
}
public static <T extends Enum<T>> Serializer<T> serialize(T victim) {
return new Serializer<T>(victim);
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
// Sender usage
EnumUtil.serialize(AwesomeEnum.Something).to(intent);
// Receiver usage
AwesomeEnum result =
EnumUtil.deserialize(AwesomeEnum.class).from(intent);
Run Code Online (Sandbox Code Playgroud)
方案3(与Kotlin一起):
已经有一段时间了,但从现在开始我们有Kotlin,我想我会为新范例添加另一种选择.在这里,我们可以使用扩展函数和已知类型(在编译时保留类型).
inline fun <reified T : Enum<T>> Intent.putExtra(victim: T): Intent =
putExtra(T::class.qualifiedName, victim.ordinal)
inline fun <reified T: Enum<T>> Intent.getEnumExtra(): T? =
getIntExtra(T::class.qualifiedName, -1)
.takeUnless { it == -1 }
?.let { T::class.java.enumConstants[it] }
Run Code Online (Sandbox Code Playgroud)
这样做有一些好处.
inline因为它将用函数内的代码替换调用.用法:
// Sender usage
intent.putExtra(AwesomeEnum.SOMETHING)
// Receiver usage
val result = intent.getEnumExtra<AwesomeEnum>()
Run Code Online (Sandbox Code Playgroud)
Ode*_*rik 114
你可以使你的enum实现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];
}
};
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用Intent.putExtra(String,Parcelable).
更新:请注意wreckgar的评论,enum.values()在每次通话时分配一个新阵列.
更新:Android Studio具有ParcelableEnum实现此解决方案的实时模板.(在Windows上,使用Ctrl+ J)
Cam*_*mer 24
您可以将枚举作为字符串传递.
public enum CountType {
ONE,
TWO,
THREE
}
private CountType count;
count = ONE;
String countString = count.name();
CountType countToo = CountType.valueOf(countString);
Run Code Online (Sandbox Code Playgroud)
在支持字符串的情况下,您应该能够毫无问题地传递枚举值.
小智 21
要通过意图传递枚举,您可以将枚举转换为整数.
例如:
public enum Num{A ,B}
Run Code Online (Sandbox Code Playgroud)
发送(枚举为整数):
Num send = Num.A;
intent.putExtra("TEST", send.ordinal());
Run Code Online (Sandbox Code Playgroud)
接收(整数到枚举):
Num rev;
int temp = intent.getIntExtra("TEST", -1);
if(temp >= 0 && temp < Num.values().length)
rev = Num.values()[temp];
Run Code Online (Sandbox Code Playgroud)
最好的祝福.:)
Jan*_*kel 15
如果你真的需要,可以使用name()和序列化enum作为String,valueOf(String)如下所示:
class Example implements Parcelable {
public enum Foo { BAR, BAZ }
public Foo fooValue;
public void writeToParcel(Parcel dest, int flags) {
parcel.writeString(fooValue == null ? null : fooValue.name());
}
public static final Creator<Example> CREATOR = new Creator<Example>() {
public Example createFromParcel(Parcel source) {
Example e = new Example();
String s = source.readString();
if (s != null) e.fooValue = Foo.valueOf(s);
return e;
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果你的枚举有可变状态(他们不应该,真的),这显然不起作用.
| 归档时间: |
|
| 查看次数: |
95494 次 |
| 最近记录: |