如何在Android上读取和写入Enum到包裹?

Fig*_*gör 41 enums android parcel parcelable

这是我的模型类:

public enum Action {
    RETRY, SETTINGS
}

private int imageId;
private String description;
private String actionName;
private Action action;

public NetworkError(int imageId, String description, String actionName, Action action ) {
    this.imageId = imageId;
    this.description = description;
    this.actionName = actionName;
    this.action = action;
}

public int getImageId() {
    return imageId;
}

public void setImageId(int imageId) {
    this.imageId = imageId;
}

public String getDescription() {
    return description;
}

public void setDescription(String description) {
    this.description = description;
}

public String getActionName() {
    return actionName;
}

public void setActionName(String actionName) {
    this.actionName = actionName;
}


@Override
public int describeContents() {
    return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeInt(this.imageId);
    dest.writeString(this.description);
    dest.writeString(this.actionName);
}

protected NetworkError(Parcel in) {
    this.imageId = in.readInt();
    this.description = in.readString();
    this.actionName = in.readString();
}

public static final Parcelable.Creator<NetworkError> CREATOR = new Parcelable.Creator<NetworkError>() {
    @Override
    public NetworkError createFromParcel(Parcel source) {
        return new NetworkError(source);
    }

    @Override
    public NetworkError[] newArray(int size) {
        return new NetworkError[size];
    }
};
Run Code Online (Sandbox Code Playgroud)

mil*_*nkb 52

我有类似的问题,我的解决方案是:

parcel.writeString(this.questionType.name());
Run Code Online (Sandbox Code Playgroud)

和阅读:

this.questionType = QuestionType.valueOf(parcel.readString());
Run Code Online (Sandbox Code Playgroud)

QuestionType 是枚举,并记住元素的排序很重要.


Bre*_*ley 28

最高效 - 内存高效 - bundle是使用ENUM序数值创建的.

写给包裹 dest.writeInt(enum_variable.ordinal());

从包裹中读取 enum_variable = EnumName.values()[in.readInt()];

这应该没问题,除非你不注意文档的警告:

包裹不是通用序列化机制.此类(以及用于将任意对象放入包中的相应Parcelable API)被设计为高性能IPC传输.因此,将任何Parcel数据放入持久存储中是不合适的:Parcel中任何数据的底层实现的更改都可能导致旧数据不可读.

换句话说,您不应该在代码版本之间传递Parcel,因为它可能不起作用.

  • 我已经可以看到人们积极支持“string”答案而不是“ordinal”答案,因为通常情况下你总是不鼓励使用“.ordinal()”,但考虑到你提到的警告,这是可接受的用途之一案例 (2认同)

Gee*_*ist 23

任何enum都是可序列化的.

你可以这样做writeToParcel():dest.writeSerializable(action)

在构造函数中: action = (Action) in.readSerializable()

  • 这是最容易实现的解决方案,但是考虑到`serializable`接口比`parcelable'慢得多,我想知道这对性能是否有任何影响,而下面的答案是你将`enum`转换为更原始的类型. (5认同)

Jag*_*esh 5

枚举减法:

public enum Action {

    NEXT(1),
    OK(2);

    private int action;

    Action(int action) {
        this.action = action;
    }

}
Run Code Online (Sandbox Code Playgroud)

从包裹中读取:

protected ActionParcel(Parcel in) {
    int actionTmp = in.readInt();
    action = Tutorials.Action.values()[actionTmp];
}
Run Code Online (Sandbox Code Playgroud)

写入包裹:

public void writeToParcel(Parcel dest, int flags) {
    int actionTmp = action == null ? -1 : action.ordinal();
    dest.writeInt(actionTmp);
}
Run Code Online (Sandbox Code Playgroud)


Aye*_*tto 5

现在,您可以使用 Kotlin Parcelize 编写如下内容:

import android.os.Parcelable
import kotlinx.parcelize.Parcelize

@Parcelize
class NetworkError(
    var imageId: Int,
    var description: String,
    var actionName: String,
    private val action: Action
): Parcelable {

    @Parcelize
    enum class Action: Parcelable {
        RETRY, SETTINGS
    }
}
Run Code Online (Sandbox Code Playgroud)