由于枚举不是原始类型,在Android中通过aidl接口传递枚举的最有效方法是什么?有没有办法首先将枚举转换为序数?
答案 0 :(得分:8)
我只是使用
String enumString = myEnum.name()
(以MyEnum为枚举,myEnum为值)获取String表示,然后
MyEnum myEnum = MyEnum.valueOf(enumString)
从String表示重构enum。
使用Ordinals可能会快一些,但如果我稍后可以添加Enums,这更有可能破坏旧代码。
//编辑:由于我不喜欢将String作为返回类型,我现在实现了像这里提到的Parcellable:Passing enum or object through an intent (the best solution)
导入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];
}
};
}
答案 1 :(得分:5)
除
String
之外的非基本类型需要方向指示符。方向指标包括in
,out
和inout
。
请查看相关的官方文档:http://developer.android.com/guide/developing/tools/aidl.html#aidlsyntax
此外,您可以考虑传递枚举的字符串或序数表示,并在需要时将其转换回来。这取自Effective Java 2nd edition:
// 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
答案 2 :(得分:0)
是的,您可以通过AIDL传递枚举,但是您必须在枚举类型上实现Parcelable。
1:一个可打包的实现。
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: 包com.cyberdyne.media;
可包裹的重复模式;
并记住将枚举参数标记为参数。
当您考虑它时,很明显。但是我敢打赌Google不会在IBinder接口中使用很多枚举。我照做(感谢您的Android Studio提供了“可实现的打包”功能,该功能并非完全适用于枚举,但是使事情相对容易了。)
在Android枚举上的分歧:
针对Android中的枚举的最佳实践建议已于许多月前撤消。您正在为可怕的可怕代码交易大约200字节的可执行文件。自Android 1.0以来,手机已经走了很长一段路。这很容易。使用枚举。 (或者使用Google使用的疯狂的Kotlin驱动的属性系统。祝您好运。)
可追溯到原始Java语言规范的正式Java知识不鼓励使用裸ordinal()。推理:维护者在更深的将来可能会不经意间重新订购普通订单并破坏东西。坦白说,我认为这是夸张的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]);
}
如果没有其他要求,它将标记该类为可能保留整数的类。评论永远不会受伤,这使编组枚举的接收端更漂亮(也更安全一点)。