web-dev-qa-db-fra.com

Comment lire et écrire Enum dans un colis sur Android?

Voici ma classe de modèle:

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

J'ai eu un problème similaire et ma solution était:

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

et pour lire:

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

QuestionType est une énumération et n'oubliez pas que l'ordre des éléments est important.

48
milosnkb

Le bundle le plus efficace - efficace en mémoire - est créé en utilisant la valeur ordinale ENUM.

Ecrire dans la parcelle dest.writeInt(enum_variable.ordinal());

Lecture depuis la parcelle enum_variable = EnumName.values()[in.readInt()];

Cela devrait être bien sauf si vous ne tenez pas compte des avertissements de la documentation:

Le colis n'est pas un mécanisme de sérialisation à usage général. Cette classe (et l'API Parcelable correspondante pour placer des objets arbitraires dans une parcelle) est conçue comme un transport haute performance IPC. En tant que tel, il n'est pas approprié de placer des données de parcelle dans des données persistantes stockage: les modifications de l'implémentation sous-jacente de l'une des données du colis peuvent rendre les données plus anciennes illisibles.

En d'autres termes, vous ne devez pas transmettre de parcelles entre les versions de code car cela peut ne pas fonctionner.

27
Brendon Whateley

Tout enum est sérialisable.

Vous pouvez le faire dans writeToParcel(): dest.writeSerializable(action)

Et dans le constructeur: action = (Action) in.readSerializable()

21
Geekarist

Déclaration d'énumération:

public enum Action {

    NEXT(1),
    OK(2);

    private int action;

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

}

Lecture du colis:

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

Écriture sur le colis:

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

Une façon de le faire est d'écrire des actions en entier et de les lire correctement en tant qu'entiers et de les convertir en action. Ce que je veux dire:

@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;
}

Essayez-le. Succès ...

2
Ahmed Matem Ahmed