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!
Vous pouvez utiliser Parcel.writeValue
pour rassembler un objet générique avec une valeur nulle.
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.
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;
}
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).