【问题标题】:Passing enums through aidl interfaces通过aidl接口传递枚举
【发布时间】:2011-02-08 18:44:54
【问题描述】:

由于枚举不是原始类型,通过 Android 中的aidl 接口传递枚举的最有效方法是什么?有没有办法先将枚举转换为序数?

【问题讨论】:

  • 看看查理柯林斯的评论。这是完全正确的:尽可能避免使用枚举。
  • @Cristian 需要谨慎对待。枚举是很好的设计。 android 不从语言中删除枚举是有原因的。
  • 那是真的,伙计。但是,我认为他们没有移动它,因为它并不那么容易。在对字节码进行索引之前,他们仍然使用javac。无论如何...我喜欢枚举,并在它们使事情变得清晰和优雅时使用它们。
  • 枚举在应用程序代码中非常好。框架作者在一组不同的约束下工作。 (例如,比较 MFC 如何在其许多核心类中避免使用虚函数。)特别是对于 Android,早期测试表明枚举比常量消耗更多的内存,因此框架避免了它们。 YMMV。事实上,您的里程有所不同,因此请为您的应用做正确的事情,而不是只做其他人都在做的事情。
  • 在深层网络的某个地方,Google 允许我们在 Android 代码中使用枚举。一个枚举在 600 字节附近的某个地方。自 Android 1.0 以来,手机已经走过了漫长的道路。去吧。

标签: java android enums primitive aidl


【解决方案1】:

我只是用

String enumString = myEnum.name() 

(以 MyEnum 作为枚举,以 myEnum 作为值)获取字符串表示,然后

MyEnum myEnum = MyEnum.valueOf(enumString) 

从字符串表示重构枚举。

使用序数可能会快一点,但如果我以后可以添加枚举,这更有可能破坏旧代码。

//编辑:因为我不喜欢将 String 作为返回类型,所以我现在实现了 Parcellable,如下所述:Passing enum or object through an intent (the best solution)

导入android.os.Parcel; 导入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];
    }
};

}

【讨论】:

【解决方案2】:

String 以外的非原始类型需要方向指示符。方向指标包括inoutinout

查看官方文档: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

【讨论】:

  • 如果可以的话,您还应该考虑完全避免使用枚举(在 Android 项目中)。 developer.android.com/guide/practices/design/…
  • 不幸的是,我没有选择避免枚举;这是一个合作项目。我可以提取枚举值的序数吗?
  • @CharlieCollins That 建议已被收回。
【解决方案3】:

是的,您可以通过 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];
    }
}
  1. 导入:

    重复模式.aidl: 包 com.cyberdyne.media;

    可打包的RepeatMode;

  2. 记得将枚举参数标记为参数。

想想就明白了。但我打赌谷歌不会在 IBinder 接口中使用大量枚举。我虽然这样做。 (感谢 Android 工作室提供“Implement Parcelable”,它并不完全适用于枚举,但让事情变得相对容易)。

关于 Android 枚举的讨论:

针对 Android 中的枚举的最佳实践建议已在很多个月前被撤回。您正在用大约 200 字节的可执行文件来换取可怕的可怕代码。自 Android 1.0 以来,手机已经走过了漫长的道路。这是不费吹灰之力的。使用枚举。 (或者使用 Google 使用的疯狂的 Kotlin 驱动的属性系统。祝你好运。)

可追溯到原始 Java 语言规范的官方 Java Lore 不鼓励使用裸序号()。推理:在遥远的未来,维护者可能会不知不觉地重新排序序数并破坏东西。坦率地说,我认为这是自大的 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]);
}

如果没有别的,它会将类标记为可能保留整数的类。并且评论永远不会受到伤害,它使编组枚举的接收端更漂亮(而且更安全一点)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-29
    • 2023-01-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多