web-dev-qa-db-fra.com

Comment sérialiser la valeur nulle lors de l'utilisation de l'interface Parcelable

concernant mon exemple de code vers le bas, que dois-je faire si l'une des variables d'un Locable est nulle? Par exemple, maintenant si l.getZoom () renvoie null, j'ai obtenu NullPointerException.

@Override
public void writeToParcel(Parcel parcel, int arg1) {
    parcel.writeInt(count);
    for(Locable l:locableArr){
        parcel.writeInt(l.getOriginId());
        parcel.writeInt(l.getLocableType());
        parcel.writeInt(l.getZoom());
        parcel.writeDouble(l.getLatituda());
        parcel.writeDouble(l.getLongituda());
        parcel.writeString(l.getTitle());
        parcel.writeString(l.getSnipet());
    }

}

Merci!

60
igor.beslic

Vous pouvez utiliser Parcel.writeValue pour rassembler un objet générique avec une valeur nulle.

102
artch

J'utilise une classe Parcelable qui a également des champs Integer et Boolean, et ces champs peuvent être nuls.

J'ai eu du mal à utiliser le générique Parcel.writeValue méthode, en particulier lorsque j'essayais de le lire via Parcel.readValue. J'ai continué à recevoir une exception d'exécution qui disait qu'il ne pouvait pas comprendre le type de l'objet parcellaire.

Finalement, j'ai pu résoudre le problème en utilisant Parcel.writeSerializable et Parcel.readSerializable avec un type cast, car Integer et Boolean implémentent l'interface Serializable. Les méthodes de lecture et d'écriture gèrent les valeurs null pour vous.

19
Justin Hong

Voici la solution que j'ai trouvée pour écrire des chaînes en toute sécurité:

private void writeStringToParcel(Parcel p, String s) {
    p.writeByte((byte)(s != null ? 1 : 0));
    p.writeString(s);
}

private String readStringFromParcel(Parcel p) {
    boolean isPresent = p.readByte() == 1;
    return isPresent ? p.readString() : null;
}
14
Felipe Lima

La plupart des codes de sérialisation que j'ai vus utilisent l'un ou l'autre des drapeaux pour indiquer la présence/l'absence d'une valeur OR précède la valeur avec un champ de comptage (par exemple, lors de l'écriture de tableaux) où le champ de comptage est il suffit de mettre à zéro si la valeur n'existe pas du tout.

L'examen du code source de Android core classes révèle du code comme celui-ci (de la classe Message):

    if (obj != null) {
        try {
            Parcelable p = (Parcelable)obj;
            dest.writeInt(1);
            dest.writeParcelable(p, flags);
        } catch (ClassCastException e) {
            throw new RuntimeException(
                "Can't marshal non-Parcelable objects across processes.");
        }
    } else {
        dest.writeInt(0);
    }

ou ceci (de la classe Intent):

    if (mCategories != null) {
        out.writeInt(mCategories.size());
        for (String category : mCategories) {
            out.writeString(category);
        }
    } else {
        out.writeInt(0);
    }

Ma suggestion: Dans votre code, s'il n'y a pas de différence fonctionnelle entre "zoom == null" et "zoom == 0", alors je déclarerais simplement le zoom comme une primitive (int au lieu de Integer) OR initialisez-le à zéro dans le constructeur et assurez-vous de ne jamais le mettre à null (alors vous pouvez être assuré qu'il ne sera jamais nul et vous n'aura pas à ajouter de code spécial pour gérer cela dans vos méthodes de sérialisation/désérialisation).

13
David Wasser