web-dev-qa-db-ja.com

AndroidでパーセルにEnumを読み書きする方法は?

モデルクラスは次のとおりです。

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];
    }
};
37
Figen Güngör

私は同様の問題を抱えていて、私の解決策は次のとおりでした:

parcel.writeString(this.questionType.name());

そして読書のために:

this.questionType = QuestionType.valueOf(parcel.readString());

QuestionTypeは列挙型であり、要素の順序が重要であることを忘れないでください。

48
milosnkb

最も効率的な-メモリ効率の良い-バンドルは、ENUM順序値を使用して作成されます。

パーセルへの書き込みdest.writeInt(enum_variable.ordinal());

区画enum_variable = EnumName.values()[in.readInt()];からの読み取り

ドキュメントの警告に注意しない限り、これは問題ないはずです。

パーセルは、汎用のシリアル化メカニズムではありません。このクラス(および任意のオブジェクトをパーセルに配置するための対応するParcelable API)は、高性能IPC=トランスポートとして設計されています。したがって、パーセルデータを永続的に配置することは適切ではありませんストレージ:パーセル内のデータの基になる実装の変更により、古いデータが読み取れなくなる可能性があります。

つまり、コードバージョン間でパーセルを渡すことはできません。

27

enumはすべてシリアル化可能です。

writeToParcel()でこれを行うことができます:dest.writeSerializable(action)

そしてコンストラクターで:action = (Action) in.readSerializable()

21
Geekarist

列挙型の宣言:

public enum Action {

    NEXT(1),
    OK(2);

    private int action;

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

}

小包からの読み取り:

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

小包への書き込み:

public void writeToParcel(Parcel dest, int flags) {
    int actionTmp = action == null ? -1 : action.ordinal();
    dest.writeInt(actionTmp);
}
3
Jagadeesh

これを行う1つの方法は、整数でアクションを書き込み、整数として適切に読み取り、アクションに変換することです。私が意味したのは:

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

    int actionAsInt = action == Action.RETRY ? 1 : 0;
    dest.writeInt(actionAsInt);
}

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

    int actionAsInt = in.readInt();
    this.action = actionAsInt == 1 ? Action.RETRY : Action.SETTINGS;
}

それを試してみてください。成功 ...

2