由于枚举类型不是原始类型,因此在Android中通过AIDL接口传递枚举的最有效方法是什么?是否有一种将枚举转换为序数的方法?
我只是使用
String enumString = myEnum.name()
(使用枚举类型 MyEnum 和值 myEnum) 获取字符串表示,然后
MyEnum myEnum = MyEnum.valueOf(enumString)
重新构建枚举类型需要使用字符串表示。
虽然使用序号可能会更快,但是如果以后需要添加枚举类型,这很可能会破坏旧代码。
//编辑:由于我不喜欢返回类型为字符串,我现在已经按照此处所述实现了Parcellable:通过意图传递枚举或对象(最佳解决方案)
import android.os.Parcel; import android.os.Parcelable;
enum InitResponse implements Parcelable {
// Everything is fine.
SUCCESS,
// Something else
FOO;
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(final Parcel dest, final int flags) {
dest.writeString(name());
}
public static final Creator<InitResponse> CREATOR = new Creator<InitResponse>() {
@Override
public InitResponse createFromParcel(final Parcel source) {
return InitResponse.valueOf(source.readString());
}
@Override
public InitResponse[] newArray(final int size) {
return new InitResponse[size];
}
};
}
String
,需要方向指示符。 方向指示符包括 in
、out
和 inout
。请参阅官方文档:http://developer.android.com/guide/developing/tools/aidl.html#aidlsyntax。此外,您可以考虑传递枚举的字符串或序数表示,并在需要时进行翻译。这是来自Effective Java第2版的建议:// Implementing a fromString method on an enum type
private static final Map<String, Operation> stringToEnum = new HashMap<String, Operation>();
static { // Initialize map from constant name to enum constant
for (Operation op : values())
stringToEnum.put(op.toString(), op);
} // Returns Operation for string, or null if string is invalid
public static Operation fromString(String symbol) {
return stringToEnum.get(symbol);
}
Operation
是一个 enum
。
public enum Badges{
GOLD, SILVER, BRONZE;
}
// somewhere else:
int ordinal = Badges.SILVER.ordinal();// this should be 1
是的,你可以通过AIDL传递枚举类型,但是你必须在枚举类型上实现Parcelable接口。
1:一个Parcelable实现。
public enum RepeatMode implements Parcelable {
NoRepeat,
RepeatAll,
RepeatTrack,
;
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(toInteger());
}
@Override
public int describeContents() {
return 0;
}
public static final Creator<RepeatMode> CREATOR = new Creator<RepeatMode>() {
@Override
public RepeatMode createFromParcel(Parcel in) {
return RepeatMode.fromInteger(in.readInt());
}
@Override
public RepeatMode[] newArray(int size) {
return new RepeatMode[size];
}
};
public int toInteger() { return this.ordinal(); }
public static RepeatMode fromInteger(int value)
{
return values()[value];
}
}
一个导入:
RepeatMode.aidl: package com.cyberdyne.media;
可重复的 RepeatMode;
记得将枚举参数标记为输入参数。
当你想到它时,这种做法似乎很明显。但我敢打赌 Google 在 IBinder 接口中并不常用枚举类型。尽管如此,我仍然这样做。(感谢 Android Studio 提供的“实现 Parcelable”,虽然对于枚举类型并不完全有效,但使事情相对容易)。
关于 Android 枚举的讨论:
多年前,最佳实践建议避免在 Android 中使用枚举类型。你会因为可怕的代码而交换大约 200 字节的可执行文件。自 Android 1.0 以来,手机已经发展了很长时间。毫无疑问,应该使用枚举类型。(或者使用 Google 使用的疯狂的 Kotlin 驱动属性系统。祝你好运。)
官方 Java 知识库追溯到最初的 Java 语言规范,反对使用裸的 ordinal()。原因是:在未来的维护期间,维护人员可能会无意中重新排序 ordinals 并破坏一些东西。坦白地说,我认为这是自命不凡的 Java 糊涂话。我为此苦苦挣扎了很长时间,在经过深思熟虑后,我妥协了。
public enum Badges {
GOLD,SILVER, BRONZE; // Must match @array/badge_states
public int toInteger() { return this.ordinal(); }
public static Badges fromInteger(int value) { return values()[value]);
}
javac
。无论如何……我喜欢枚举,并在它们能使事情变得清晰优雅时使用它们。 - Cristian